MySQL RR隔离级别
tbghg

以前搞不明白RR不能解决幻读,但是又说RR可以用间隙锁、临界锁、MVCC解决幻读,于是详细捋了一下。简单来说是RR可以通过间隙锁、临界锁、MVCC 解决部分幻读,但不能解决全部的,想要完全解决需要串行化。

幻读与不可重复读区别

“幻读”是指读的过程中,某些元组被增加、删除,这样进行一些集合操作,比如算总数,平均值等等,就会每次算出不一样的数。

不可重复读:一个事务先后读取同一条记录,但两次读取的数据不同

RR与RC的区别

SQL 标准定义了四个隔离级别:

隔离级别

  • READ-UNCOMMITTED(读取未提交): 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读
  • READ-COMMITTED(读取已提交): 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
  • REPEATABLE-READ(可重复读): 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生
  • SERIALIZABLE(可串行化): 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读

区别

锁方面的区别

显然 RR 支持 gap lock(next-key lock),而RC则没有gap lock。因为MySQL的RR需要gap lock来解决幻读问题。而RC隔离级别则是允许存在不可重复读和幻读的。所以RC的并发一般要好于RR

一致性读

RC隔离级别时,事务中的每一条select语句会读取到他自己执行时已经提交了的记录,也就是每一条select都有自己的一致性读ReadView

而RR隔离级别时,事务中的一致性读的ReadView是以第一条select语句的运行时,作为本事务的一致性读snapshot的建立时间点的。只能读取该时间点之前已经提交的数据。

RC 支持半一致性读,RR不支持

对比RR隔离级别,update语句会使用当前读,如果一行被锁定了,那么此时会被阻塞,发生锁等待。而不会读取最新的提交版本,然后来判断是否符合where条件。

半一致性读的优点:减少了update语句时行锁的冲突;对于不满足update更新条件的记录,可以提前放锁,减少并发冲突的概率。

参考文章

以前随手做的笔记,忘记记录参考文章了,抱歉

 评论
评论插件加载失败
正在加载评论插件