mysql为什么使用RR(REPEATABLE READ)作为默认事务隔离机制

一 事务的隔离级别

从低到高为:读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)、串形(Serializable),后三种分别可以解决脏读、不可用重复读、幻读的问题。

二 MySQL为什么要选择RR作为默认隔离级别

1 RC隔离级别太低,不利于数据安全性;Serializable隔离级别太高,不利于接口并发。

2 MySQL的RR隔离机制,使用了间隙锁(GAP Lock),配合MVCC机制可以在一定程度上避免幻读(如果要完全解决幻读的问题,还是需要使用Serializable)。因此,使用RR,不仅可以解决脏读、不可重复读,也可以在一定程度上解决幻读的问题。

tips:在MVCC机制下,事务都是进行快照读,因此大部分情况下不会出现幻读。但是,如果在事务A进行了快照读后,事务B插入新数据并提交,此时事务A可以update B新插入的这条数据成功,也是发生了幻读。因此,要想彻底解决幻读,需要采用Serializable隔离级别。

3 为了兼容binlog的statement格式。详见下文。

三 binlog的格式

binlog用于主从之间同步数据,其中存储的数据有三种格式:statementrowmixed

statement格式存储的就是执行的sql语句,使用简单、占用存储空间小

row格式存储的是每行修改前后的数据,恢复数据精确,但是占用空间大

mixed是statement和row格式的折衷,mysql会根据每条sql命令决定采用哪种格式存储。

statement格式有个问题,举个例子,采用RC的隔离级别,两个事务A、B,A事务执行删除小于100的行,B事务执行插入一条值为90的行。A先开始执行事务,中途B再开始,但是B先提交,A最后提交。主库中由于事务A读取不到B未提交的数据,因此最终会把90插入进去。

sessionAsessionB
set session transaction isolation level read committed;
set autocommiteed=0;set session transaction isolation level read committed;
set autocommiteed=0;
begin;begin;
delete from t where b<100;
insert into t values(90);
commit;
commit;

根据事务提交的顺序,binlog中就会顺序写入insert、delete两条命令。从库根据binlog同步数据,最终的结果就是把B插入的数据90也删了,导致主从不一致。

而如果使用RR的隔离级别,A会在更新数据的时候加间隙锁(GAP Lock)和临键锁(Next Key Lock),事务B会等待A提交或者回滚完成之后再执行,就解决了这个问题。因此Mysql默认使用RR作为事务隔离机制。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值