# 事务A,Transaction ID 100begin ;UPDATE account SET balance = 1000WHERE id = 1;commit;复制代码
在事务B中,执行更新操作,把id=1的记录balance修改为2000,更新完后,undo 日志链如下:
# 事务B,Transaction ID 200begin ; //开个事务,占坑先UPDATE account SET balance = 2000WHERE id = 1;复制代码
文章插图
回到事务C,执行查询2
# 事务C,Transaction ID 300begin ;//查询1:select * fromaccount WHERE id = 1;//查询2:select * fromaccount WHERE id = 1;复制代码
查询2:执行分析:- 在RR 级别下,执行查询2的时候,因为前面ReadView已经生成过了,所以直接服用之前的ReadView,活跃事务列表为[100,200].
- 由上图undo日志链可得,最新版本的balance为2000,它的事务ID为200,在活跃事务列表里,所以当前事务(事务C)不可见 。
- 我们继续找下一个版本,balance为1000这行记录,事务Id为100,也在活跃事务列表里,所以当前事务(事务C)不可见 。
- 继续找下一个版本,balance为100这行记录,事务Id为50,小于活跃事务ID列表最小记录100,所以这个版本可见,因此,查询2的结果,也是返回balance=100这个记录~~
- 共享锁(S锁):允许持锁事务读取一行 。
- 排他锁(X锁):允许持锁事务更新或者删除一行 。
- T2 请求 s 锁立即被允许,结果 T1 T2 都持有 r 行的 s 锁
- T2 请求 x 锁不能被立即允许
记录锁(Record Locks)
- 记录锁是最简单的行锁,仅仅锁住一行 。如:SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE
- 记录锁永远都是加在索引上的,即使一个表没有索引,InnoDB也会隐式的创建一个索引,并使用这个索引实施记录锁 。
- 会阻塞其他事务对其插入、更新、删除
RECORD LOCKS space id 58 page no 3 n bits 72 index `PRIMARY` of table `test`.`t` trx id 10078 lock_mode X locks rec but not gapRecord lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 0: len 4; hex 8000000a; asc;; 1: len 6; hex 00000000274f; asc'O;; 2: len 7; hex b60000019d0110; asc;;复制代码
间隙锁(Gap Locks)- 间隙锁是一种加在两个索引之间的锁,或者加在第一个索引之前,或最后一个索引之后的间隙 。
- 使用间隙锁锁住的是一个区间,而不仅仅是这个区间中的每一条数据 。
- 间隙锁只阻止其他事务插入到间隙中,他们不阻止其他事务在同一个间隙上获得间隙锁,所以 gap x lock 和 gap s lock 有相同的作用 。
- Next-key锁是记录锁和间隙锁的组合,它指的是加在某条记录以及这条记录前面间隙上的锁 。
假设account表有4条数据 。
- 开启事务A,执行当前读,查询id>2的所有记录 。
- 再开启事务B,插入id=5的一条数据 。
- 事务B插入数据成功后,再修改id=3的记录
- 回到事务A,再次执行id>2的当前读查询
文章插图
- 事务B可以插入id=5的数据,却更新不了id=3的数据,陷入阻塞 。证明事务A在执行当前读的时候在id =3和id=4这两条记录上加了锁,但是并没有对 id > 2 这个范围加锁~
- 事务B陷入阻塞后,切回事务A执行当前读操作时,死锁出现 。因为事务B在 insert 的时候,会在新纪录(id=5)上加锁,所以事务A再次执行当前读,想获取id> 3 的记录,就需要在 id=3,4,5 这3条记录上加锁,但是 id = 5这条记录已经被事务B 锁住了,于是事务A被事务B阻塞,同时事务B还在等待 事务A释放 id = 3上的锁,最终产生了死锁 。
文章插图
因此,我们可以发现,RC隔离级别下,加锁的select, update, delete等语句,使用的是记录锁,其他事务的插入依然可以执行,因此会存在幻读~
推荐阅读
- 荨麻疹能彻底治好吗
- 一通百通,一文实现灵活的 K8S 基础架构
- 一文带你了解搜索功能设计
- 翡翠|一文读懂翡翠的种
- 彻底弄透Java处理GMT/UTC日期时间
- 微软|诞生25年后:Windows彻底告别SMB1传输协议
- 一文看懂 HashMap 中的红黑树实现原理
- 一文看懂HMS Core到底是什么
- 通过实验读懂神经网络识别VPN行为
- 建议收藏 一文深度讲解JVM 内存分析工具 MAT及实践