mysql(InnoDB)事务隔离级别(REPEATABLE READ) 与 锁,MVCC
REPEATABLE READ
(可重复读)
之前已经了解到, 该隔离级别可以解决
不可重复读问题
(当然, 也能解决脏读问题
), 那么如果单纯用锁来实现, 可能会是如下这样子:- 既然
REPEATABLE READ
隔离级别可以解决脏读
,不可重复读
的问题, 也就是它既可以让事务只能读其他事务已提交的的记录, 又能在同一事务中保证多次读取的数据即使被其他事务修改, 也是一致的。 - 解决
脏读问题
:
试想一下, 当在事务A中读取数据D的时候, 假设D之前已经在事务B中了, 并且事务B中对数据D做了修改, 但是事务B还没有完成(commit/rollback), 那如何让事务A无法读取数据D呢?
当事务B在对数据D做写操作的时候, 假设给数据D加上了行级的排他锁(X lock), 那事务A自然只能阻塞等事务A完成后才能读取数据D了, 这样就解决了脏读问题
。 - 解决
不可重复读问题
:
试想一下, 当在事务A中第一次读取了数据D之后, 直接给该数据D加S共享锁, 那其他事务自然只能阻塞等事务A完成后才能对数据D做修改操作了, 这样就解决了不可重复读
, 在事务A中多次读取数据D, 都是一样的。
- 既然
上面使用
S锁+X锁
确实可以实现READ COMMITTED
隔离级别的效果, 也就避免了脏读问题
和不可重复读问题
, 当然, 这里的问题仍然是低效!!!!因为 MySQL 在事务隔离级别Read committed 、Repeatable Read下,InnoDB 存储引擎采用
非锁定
的一致性读
--即读取数据不用加锁,即采用的是MVCC中一致性非锁定读
模式, 所以, InnoDB的做法是: 读不影响写,写不影响读。- 读不影响写: 当数据正在执行读操作时,其他事务的写操作不会因此去等待当前事务行上S锁的释放,而是会去读取行的一个快照数据。
- 写不影响读:当数据正在执行写操作时,其他事务的读操作不会因此去等待当前事务行上X锁的释放,而是会去读取行的一个快照数据。
- 所以总结来看,
READ UNCOMMITTED
和REPEATABLE READ
这两个隔离级别都是使用写用排他锁 + 读用MVCC
, 区别可以参考 MySQL-InnoDB-MVCC多版本并发控制
相关推荐
DriveCar 2020-09-07
quniMdejiangyou 2020-08-15
silencehgt 2020-07-04
zhanbuquan 2020-07-04
liaomingwu 2020-06-25
zhanbuquan 2020-06-21
vincen 2020-06-10
zjx0 2020-05-20
愿天下再无BUG 2020-05-16
MissFuTT 2020-05-11
好记忆也需烂 2020-05-10
wenjieyatou 2020-05-06
bluet00 2020-05-05
jiong 2020-04-19
逍遥斩舞 2020-04-17
achiverhai 2020-04-16
zhengsj 2020-03-28
lpfvip00 2020-06-25
variab 2020-06-13
sunysh00 2020-06-11
DriveCar 2020-06-09
sofast 2020-06-03
weikaixxxxxx 2020-05-30
neweastsun 2020-05-27
sunysh00 2020-05-25
pengpengflyjhp 2020-05-14
inhumming 2020-05-10
silencehgt 2020-05-09