安全基础 --- MySQL数据库的《锁》解析

MySQL的ACID

(1)ACID是衡量事务的四个特性

  • 原子性(Atomicity,或称不可分割性)
  • 一致性(Consistency)
  • 隔离性(Isolation)
  • 持久性(Durability)

(2)解析

原子性:语句要么全执行,要么全不执行,是事务最核心的特性,事务本身就是用原子性来定义的。(实现主要基于 undo log)

持久性:保证事务提交后不会因宕机导致数据丢失。(实现主要基于 redo log)

隔离性:保证事务执行尽可能不受其他事务影响;InooDB默认的隔离级别是RR,RR的实现主要基于锁机制(包含next-key lock)、MVCC(包括数据的隐藏列、基于 undo log 的版本链、ReadView)

一致性:事务追求的最终目标,一致性的实现既需要数据库层面的保障,也需要应用层面的保障

mysql的锁机制

加锁机制:乐观锁和悲观锁

(1)悲观锁

悲观锁:又称悲观并发控制,指的是数据被外界修改持保持态度,整个事务处理中,将数据进行锁定,直到事务处理完毕,才释放锁。

PS:悲观锁认为并发事物会导致问题,屏蔽一切可能违反数据一致性的操作。

特点:完全保证数据的独占性和正确性,因为每次请求都会先对数据进行加锁,然后进行数据操作,最后再解锁,加锁释放锁的过程会有消耗,所以性能不高;

(2)乐观锁

乐观锁:假设认为数据一般情况下不会造成冲突,所以在数据提交更新时候,才回正式对数据的冲突与否进行检查。

实现方式(常见):

  1. 版本号:表中新增一个版本号字段,每次数据更新都会修改版本号。更新数据会检查数据库中版本号与之前读取版本号是否一致,一致则允许修改
  2. 时间戳:类似于版本号的方式,使用数据库时间戳来实现。更新数据时会检查时间戳是否与之前读取的一致
  3. 基于字段判断:使用WHERE字句加上之前读取的字段值进行判断。更新行数为0,则表示数据已被其他事务修改,发生冲突

在提交更新之前检查是否有其他事务已经修改了该记录,如果发现修改,则会回滚更新并重试事务。否则,它会将更新提交到数据库。

兼容性:共享锁和排它锁

(1)排它锁

排它锁:又被称为写锁(简称X锁)。不能与其它事务共存,如一个事务获取了一个数据行的排它锁,其他事务就不能获取该行的其他锁,包括共享锁和排它锁。

实质:排他锁指的是一个事务在一行数据加上排他锁后,其他事务不能再在其上加其他的锁

实现:

打开第一个命令行界面

set autocommit=0; ---> 关闭自动提交
select * from users where from id=1 for update; ---> 查询语句的同时增加排它锁

打开第二个命令行界面


进程阻塞,不会再去动这个进程,除非上级事务提交


上级事务已提交

查询结果显示

存在问题:用户的体验和性能。如果用排它锁锁住,所有的读、请求都会堵塞在这里,对系统压力较大。n等多个进程全部堵塞,在等待中,释放后这些进程就会开始竞争,其中一个进程竞争到,其他进程相当于什么都没干,系统性能已消耗。 ---  惊群效应

惊群效应:当你往一群鸽子中间扔一块食物,虽然最终只有一个鸽子抢到食物,但所有鸽子都会被惊动来争夺,没有抢到食物的鸽子只好回去继续睡觉, 等待下一块食物到来。这样,每扔一块食物,都会惊动所有的鸽子,即为惊群。

(2)共享锁

共享锁:又被称为读锁(简称S锁)。多个事务对于同一数据可以共享一把锁,都能访问到数据,但是仅只读不能修改。

共享锁相对更好理解一点,就是多个事务只能读数据不能改数据。

实现:

打开第一个命令界面

select * from users where id=1 lock in share mode; --->  做共享锁

打开第二个命令界面

update users set username='oupeng' where id=1; ---> 更新users表中id=1的username

存在问题:修改数据时,该共享锁认为该线程一定会被一定会被多个线程争抢,读线程不受影响,

PS:共享锁和排它锁都属于悲观锁

mysql事务隔离级别

MySQL 事务都是指在 InnoDB 引擎下

(1)级别分类

mysql有四个事务隔离级别,每个级别都有字符或数字编号

  • 读未提交(READ-UNCOMMITTED)| 0 :存在脏读,不可重复读,幻读的问题
  • 读已提交(READ-COMMITTED) | 1:解决脏读的问题,存在不可重复读,幻读的问题
  • 可重复读(REPEATABLE-READ) | 2:解决脏读,不可重复读的问题,存在幻读的问题,默认隔离级别,使用MVVC机制,实现可重复读
  • 序列化(SERIALIZABLE) | 3:解决脏读,不可重复读,幻读的问题,保证事务安全,但完全串行执行,性能最低

查看会话的事务隔离级别:

select @@global.tx_isolation, @@tx_isolation;

默认的隔离级别为可重复读

(2)解决实际问题

  • 脏读(Dirty Read)
    脏读指的是读到了其他事务未提交的数据,未提交意味着这些数据可能会回滚,也就是可能最终不会存到数据库中,也就是不存在的数据。读到了并一定最终存在的数据,这就是脏读。
  • 可重复读(Repeatable Read)
    可重复读指的是在一个事务内,最开始读到的数据和事务结束前的任意时刻读到的同一批数据都是一致的。通常针对数据更新(UPDATE)操作。
  • 不可重复读(Non-Repeatable Read)
    对比可重复读,不可重复读指的是在同一事务内,不同的时刻读到的同一批数据可能是不一样的,可能会受到其他事务的影响,比如其他事务改了这批数据并提交了。通常针对数据更新(UPDATE)操作。
  • 幻读(Phantom Read)
    幻读多是针对数据插入(INSERT)操作来说的。事务 A 按照一定条件进行数据读取, 期间事务 B 插入了相同搜索条件的新数据,事务 A 再次按照原先条件进行读取时,发现了事务 B 新插入的数据,称为幻读
脏读演示

<1> 开启A,B两个窗口,进行如下操作:

show variables like 'autocommit';  ----  查看当前的自动提交是否开启
set autocommit = off; --- 关闭自动提交

set session transaction isolation level read uncommitted; --> 设置当前会话隔离级别为“读未提交”
select @@tx_isolation; --> 查看当前隔离级别

start transcation; --- 开启事务,(begin; -- 显式开启事务)

<2> 修改数据进行查询

B:update users set username='123456' where id=1; --- 修改id=1的username为123456
A:select * from users where id=1; --- 在A窗口查询id=1的数据 



事务未关闭,显示数据已被更改,此时出现的问题即为脏读。

不可重复读演示

<1> 关闭A,B的自动提交机制,使用读已提交隔离级别,开启事务



<2> 修改数据进行查询

B:update users set username='oupengaaa' where id=1; --- 修改id=1的username为oupengaaa
A:select * from users where id=1; --- 在A窗口查询id=1的数据



​​​​​​id=1的username未发生改变,当B窗口修改事务后未使用(commit;)提交,所以事务未发生改变。

在B窗口提交后,在A窗口进行查询

存在问题:不可重复读 --- 同一事物内,最开始读到的数据和事务结束前任意时刻读到的数据不一致。

可重复读演示

<1> 关闭A,B的自动提交机制,使用可重复读隔离级别,开启事务



<2> 修改数据进行查询

B:update users set username='oupeng1234' where id=1; --- 修改id=1的username为oupeng1234
A:select * from users where id=1; --- 在A窗口查询id=1的数据



​​​​​​id=1的username未发生改变

B窗口提交后继续查看,依旧未改变

A窗口使用(commit;)提交,查询数据改变情况

存在问题:可重复读可能产生幻读问题,幻读问题很少出现。

可重复读的实现机制:MVCC --- 多版本并发控制,类似于乐观锁的实现机制

多版本并发控制(MVCC)是一种用来解决读-写冲突的无锁并发控制,也就是为事务分配单向增长的时间戳,为每个修改保存一个版本,版本与事务时间戳关联,读操作只读该事务开始前的数据库的快照。

幻读演示(可重复读环境下)

事务T1:

事务T2:

只要 T1 和 T2 时刻执行产生的结果集是不相同的,那就发生了幻读的问题,比如:

  • T1 时间执行的结果是有 5 条行记录,而 T2 时间执行的结果是有 6 条行记录,那就发生了幻读的问题。

  • T1 时间执行的结果是有 5 条行记录,而 T2 时间执行的结果是有 4 条行记录,也是发生了幻读的问题。

由此,可把幻读理解为:select 某记录是否存在,不存在,准备插入此记录,但执行 insert 时发现此记录已存在,无法插入,此时就发生了幻读。

(3)mysql 幻读问题

MVCC + gap Lock

幻读是指在一个事务中,由于其他事务的并发操作,导致同一个查询在不同时间点返回不同的结果集。简单来说,幻读就是一个事务在读取数据的过程中,发现了一些“幻影”数据,这些数据在事务开始时不存在,但在事务结束时却突然出现了

两种解决方案

<1> 针对快照读(普通select语句):通过 MVCC 方式解决了幻读。MVCC 是一种在并发事务执行过程中管理数据版本的机制。它通过为每个事务分配唯一的事务 ID 和版本号来跟踪数据的变化。

<2> 针对当前读(select ... for update 等语句):是通过 next-key lock(记录锁+间隙锁)方式解决了幻读,因为当执行 select ... for update 语句的时候,会加上 next-key lock,如果有其他事务在 next-key lock 锁范围内插入了一条记录,那么这个插入语句就会被阻塞,无法成功插入,所以就很好了避免幻读问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/147873.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Python学习笔记之运算符的使用

Python学习笔记之运算符的使用 整型&#xff1a;二进制0b100十进制4、八进制0o100十进制64、十进制100、十六进制0x100十进制256浮点型&#xff1a;123.456&#xff0c;1.23456e2字符串型&#xff1a;‘Hello’&#xff0c;“Hello”布尔型&#xff1a;True、False复数型&…

Postgresql源码(114)视图权限授予逻辑

0 速查 被授权的对象在系统表中记录授权信息&#xff0c;例如pg_namespace中的nspacl列&#xff1a; {mingjieUC/mingjie,UC/mingjie,pusr1UC/mingjie}pusr1UC/mingjie的含义&#xff1a; mingjie是赋予者pusr1是被赋予者UC是权限&#xff0c;表示USAGE和CREATE 1 视图权限…

PHP 反序列化漏洞:身份标识

文章目录 参考环境访问修饰符访问修饰符PHP 与访问修饰符 手写身份标识身份标识定义身份标识控制字符 NUL在 PHP 中如何表示空字符&#xff1f; 通过空字符尝试构建包含非公共属性对象的序列化文本 空字符的传输控制字符的不可打印性结论另辟蹊径URL 字符编码将非 ASCII 字符文…

SpringBoot整合RocketMQ笔记

SpringBoot版本为2.3.12.Release RocketMQ对比kafka 学习链接 https://zhuanlan.zhihu.com/p/335216381 代码实战 https://www.cnblogs.com/RedOrange/p/17401238.html Centos安装rocketmq https://blog.csdn.net/chuige2013/article/details/123783612 RocketMQ详细配置与…

C++——继承

继承的概念 在C&#xff0c;继承是一种可以代码复用的重要手段&#xff0c;它允许一个类继承另一个类的属性和方法。继承可以实现类之间的层次关系&#xff0c;提供代码重用和多态性有关的功能。同时&#xff0c;C支持多重继承&#xff0c;即一个类可以继承多个基类的特性 继…

123. 买卖股票的最佳时机 III

给定一个数组&#xff0c;它的第 i 个元素是一支给定的股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。 注意&#xff1a;你不能同时参与多笔交易&#xff08;你必须在再次购买前出售掉之前的股票&#xff09;。 Ans:思路&#x…

OpenCV 实现 SIFT→SURF 算法关键点检测实现

目录 1&#xff0c;SIFT算法原理 1.1&#xff0c;基本流程 1.1.1 尺度空间极值检测 1.1.2 关键点定位 1.1.3 关键点方向确定 1.1.4 关键点描述 1.1.5 总结 1.2 SURF原理 2 代码实现 3 结果展示 4&#xff0c;你肯定会遇到报错 cv2.error: OpenCV(3.4.8) C…

网络摄像头(IPC)介绍:类型、供电、镜头、夜视等

IPC&#xff08;Internet Protocol Camera&#xff0c;网络摄像头&#xff09;&#xff0c;它是一种由传统摄像机与网络技术结合所产生的新一代摄像机。它可以将视频、音频、报警及控制信号通过网络传输&#xff0c;接受网络监控主机&#xff08;NVR或监控管理平台&#xff09;…

(SAR)Sentinel-1影像自动下载

基于ASF网站提供的python代码&#xff0c;实现Sentinel-1影像的自动下载&#xff1b; 1、登录ASF网站 登录Sentinel-1影像ASF网站&#xff1a;https://search.asf.alaska.edu/&#xff1b; 点击网站最右侧Sign in图标&#xff0c;进行用户注册&#xff1b; 注册完用户之后&…

运行程序时msvcr110.dll丢失的解决方法,msvcr110.dll丢失5的个详细解决方法

在使用电脑的过程中&#xff0c;我们经常会遇到各种问题&#xff0c;其中之一就是 msvcr110.dll 丢失的问题。msvcr110.dll 是 Microsoft Visual C Redistributable 的一个组件&#xff0c;用于支持使用 Visual C 编写的应用程序。如果您的系统中丢失了这个文件&#xff0c;您可…

stm32 - 初识2

stm32 - 初识2 工程架构点灯程序寄存器方式点灯库函数的方式点灯 工程架构 启动文件 中断向量表&#xff0c;中断服务函数&#xff0c;其他中断等 中断服务函数中的&#xff0c;复位中断是整个程序的入口&#xff0c;调用systeminit&#xff0c;和main函数 点灯程序 寄存器方式…

【论文阅读】UniDiffuser: Transformer+Diffusion 用于图、文互相推理

而多模态大模型将能够打通各种模态能力&#xff0c;实现任意模态之间转化&#xff0c;被认为是通用式生成模型的未来发展方向。 最近看到不少多模态大模型的工作&#xff0c;有医学、金融混合&#xff0c;还有CV&NLP。 今天介绍&#xff1a; One Transformer Fits All Di…

华为云云耀云服务器L实例评测 | 实例场景体验之搭建接口服务:通过华为云云耀云服务器构建 API 服务

华为云云耀云服务器L实例评测 &#xff5c; 实例场景体验之搭建接口服务&#xff1a;通过华为云云耀云服务器构建 API 服务 介绍华为云云耀云服务器 华为云云耀云服务器 &#xff08;目前已经全新升级为 华为云云耀云服务器L实例&#xff09; 华为云云耀云服务器是什么华为云云…

工地临时用电之智慧用电:全方位保障用电安全

随着科技进步和智能化的发展&#xff0c;工地用电管理也迎来了智慧化的革新。智慧用电&#xff0c;作为智慧工地的重要组成部分&#xff0c;通过集中式管理和创新的技术手段&#xff0c;为工地提供了全方位的用电安全保障。 针对工地临时用 的现状及系统结构&#xff0c;力安科…

阿里云PolarDB自研数据库详细介绍_兼容MySQL、PostgreSQL和Oracle语法

阿里云PolarDB数据库是阿里巴巴自研的关系型分布式云原生数据库&#xff0c;PolarDB兼容三种数据库引擎&#xff1a;MySQL、PostgreSQL、Oracle&#xff08;语法兼容&#xff09;&#xff0c;目前提供云原生数据库PolarDB MySQL版、云原生数据库PolarDB PostgreSQL版和云原生数…

十四天学会C++之第三天(数组和字符串)

1. 数组的定义和初始化 数组是一种由相同数据类型的元素组成的集合&#xff0c;这些元素按照一定的顺序存储在连续的内存位置上。数组的大小在创建时是固定的&#xff0c;无法在运行时改变。 在C中&#xff0c;数组的定义和声明非常简单。定义一个数组&#xff1a; 数据类型…

Django之十二:模板的继承+用户列表

模板的继承 新建layout.html&#xff1a; {% load static %} <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><link rel"stylesheet" href"{% static plugins…

C++list模拟实现

list模拟实现 1.链表结点2.类模板基本框架3.构造4.插入普通迭代器实现4.1尾插4.2普通迭代器实现4.3对比list和vector的iterator4.4迭代器的价值4.5insert4.6尾插头插复用写法 5.删除erase5.1erase5.2尾删头删复用写法 6.析构emptysizeclear6.1clear6.2size6.3 empty6.4 析构 7.…

问题: 视频颜色问题,偏绿

参考 什么是杜比视界&#xff1f; - https://www.youtube.com/watch?vldXDQ6VlC7g 【哈士亓说】07&#xff1a;HDR、杜比视界究竟是个啥&#xff1f;为什么这个视频还不是HDR视频&#xff1f; - https://www.youtube.com/watch?vrgb9Xg3cJns 正文 视频应该是 杜比视界 电…

GEO生信数据挖掘(二)下载基因芯片平台文件及注释

检索到目标数据集后&#xff0c;开始数据挖掘&#xff0c;本文以阿尔兹海默症数据集GSE1297为例 目录 下载平台文件 1.AnnotGPL参数改为TRUE,联网下载芯片平台的soft文件。&#xff08;国内网速奇慢经常中断&#xff09; 2.手工去GEO官网下载 转换芯片探针ID为gene name 拓…