####### mysql.innoDB中的乐观锁(mvcc)和悲观锁 #######

目录

三宗罪,事务并发可能出现的情况:

1. 脏读

2. 不可重复读

3. 幻读

针对三宗罪,得出的隔离级别:(在innoDB中,仅手动悲观锁的时候,而乐观锁mvcc不需要这样)

READ UNCOMMITTED(读未提交)

READ COMMITTED(读提交)

REPEATABLE READ(可重复读)

SERIALIZABLE(串行化)

mysql.innoDB中的乐观锁(mvcc)和悲观锁

参考:

悲观锁 和 乐观锁mvcc 的文章链接


三宗罪,事务并发可能出现的情况:

1. 脏读

问题概述:事务a读取,事务b修改。一个事务读到了另一个未提交事务修改过的数据。

解决方式:一个事务只能读到另一个已经提交了的修改的数据。【即:读已提交】

2. 不可重复读

概述:事务a读取,事务b修改。

解决方式:一个事务只能读到另一个已经提交的事务修改过的数据,并且其他事务每对该数据进行一次修改并提交后,该事务都能查询得到最新值。【即:可重复读】

3. 幻读

概述:事务a读取,事务b插入

针对三宗罪,得出的隔离级别:(在innoDB中,仅手动悲观锁的时候,而乐观锁mvcc不需要这样)

READ UNCOMMITTED(读未提交)

在读未提交隔离级别下,事务A可以读取到事务B修改过但未提交的数据。

可能发生脏读、不可重复读和幻读问题,一般很少使用此隔离级别。

READ COMMITTED(读已提交)

在读已提交隔离级别下,事务B只能在事务A修改过并且已提交后才能读取到事务B修改的数据。

读已提交隔离级别解决了脏读的问题,但可能发生不可重复读和幻读问题,一般很少使用此隔离级别。

REPEATABLE READ(可重复读)

在可重复读隔离级别下,事务B只能在事务A修改过数据并提交后,自己也提交事务后,才能读取到事务B修改的数据。

可重复读隔离级别解决了脏读和不可重复读的问题,但可能发生幻读问题。

一个好问题:

为什么上了写锁(写操作),别的事务还可以读操作?

因为InnoDB有MVCC机制(多版本并发控制),可以使用快照读,而不会被阻塞。

SERIALIZABLE(串行化)

事务只能串行跑,性能太差

mysql.innoDB中的乐观锁(mvcc)和悲观锁

innoDB默认乐观锁,即mvcc,涵盖增删改查,其中查询指的是快照读:select * from table ….;

悲观锁,需要手动加,例如:

select * from table where ? lock in share mode;

select * from table where ? for update;

在一个事务里,如果对某条记录的查询操作加了上述的写锁,则当前记录就只能在当前事务里被修改,即走了悲观锁机制,并其也需要维护mvcc信息,因为要始终支持乐观锁机制。

上述过程,适应于:对一条记录,先查出来,判断后,再修改的场景。

针对上述场景:

一方面,是为了保证查出来的数据是”当前读“而不是”快照读“,因为后者可能不是最近数据;

一方面,是为了防止其他的事务的修改;

所以,innoDB默认乐观锁mvcc,但可以手动走悲观锁机制,手动走悲观锁机制时也需要维护mvcc信息,因为要始终支持乐观锁机制。

所以,仅依靠mvcc是完全可以解决三个原罪的。其中,对于快照读,幻读依赖MVCC解决;对于当前读,幻读依赖间隙锁解决。

参考:

https://juejin.cn/post/6844904096378404872 (个人备份地址:https://blog.csdn.net/chushoufengli/article/details/114594009

https://developer.aliyun.com/article/743691 (个人备份地址:https://blog.csdn.net/chushoufengli/article/details/114594110

悲观锁 和 乐观锁mvcc 的文章链接

https://blog.csdn.net/chushoufengli/article/details/107283914

https://blog.csdn.net/chushoufengli/article/details/114594717

猜你喜欢

转载自blog.csdn.net/chushoufengli/article/details/114593466