以下都基于innodb
虽然MySQL的RC级别在每次读取时都会创建新的快照,这样就会存在不可重复读和幻读。但是如果加锁的话就能阻止其他事务对第一次获取到的结果集进行修改和删除,看起来应该能完全解决不可重复读的问题。可是为什么又说RC级别没有解决不可重复读呢?
注:这里说的锁不是程序代码上的加锁而是指MySQL的锁,即LBCC。
以下都基于innodb
虽然MySQL的RC级别在每次读取时都会创建新的快照,这样就会存在不可重复读和幻读。但是如果加锁的话就能阻止其他事务对第一次获取到的结果集进行修改和删除,看起来应该能完全解决不可重复读的问题。可是为什么又说RC级别没有解决不可重复读呢?
注:这里说的锁不是程序代码上的加锁而是指MySQL的锁,即LBCC。
RC 级别没有解决不可重复读
这句话单独拎出来,没问题。
加锁,能阻止其他事务对结果集进行操作
只要你加锁得当,其实就没数据库事务的问题,出现的新问题其实是:大家都加锁、加原子锁、加分布式原子锁……程序还能不能高性能的跑了?
————
最后稍微补充一句,事务其实也是锁,数据库根据采用的隔离级别,在事务中对操作数据进行检定、锁死、回滚等行为。问题是事务的锁可能是乐观锁。
所以既然谈到事务隔离,就已经是一种锁了,在这个层面上再怼一层业务锁……不太对劲。
好久没看这些知识了,所以说的不一定对。简单搜一搜,你可以参考这个:Innodb中的事务隔离级别和锁的关系 - 美团技术团队博客
5 回答3.2k 阅读✓ 已解决
3 回答2.3k 阅读✓ 已解决
3 回答3.6k 阅读✓ 已解决
2 回答2.8k 阅读✓ 已解决
1 回答2.4k 阅读✓ 已解决
1 回答2.9k 阅读✓ 已解决
5 回答1.4k 阅读
RC是数据库提供,你加锁是你业务提供的。确实不是同一个层面上的东西。RC它自己本身没有解决不可重复读,这么想就行了。要说业务支持,你开读未提交,甚至能在业务层面解决幻读的问题。不过很少人这么做,这也需要额外的大量时间,精力,和知识。
补充回答:
仅靠MVCC无法完全避免幻读,mvcc 无法避免写写冲突导致的丢失更新,而这是无法被容忍的。所以需要额外的锁的辅助来完成,而这需要额外的操作,这其实也可以理解为业务锁,只是这个锁是由mysql提供的,因为他们确实属于不同层次的东西。
不过这也并不太容易造成混乱。因为RR隔离级别已经完成了它本来的工作,解决部分幻读功能差不多相当于额外赠送的礼物,并不会对使用者造成困惑,至于要完全解决幻读,需要多一些了解,或者直接提高隔离界别。至于RC隔离级别,一样的道理,它确实能够完成本职工作--读已提交。同样,你可以使用mysql提供的锁工具来避免不可重复读,但它依然倾向于业务层面的操作和你的选择。
已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。