目录
回顾 数据库事务
#### 数据库事务 ####_wangfy_的博客-CSDN博客
事务并发可能出现的情况(三宗罪):
1. 脏读
问题概述:事务a读取,事务b修改。一个事务读到了另一个未提交事务修改过的数据。
解决方式:一个事务只能读到另一个已经提交了的修改的数据。【即:读已提交】
2. 不可重复读
概述:事务a读取,事务b修改。
解决方式:一个事务只能读到另一个已经提交的事务修改过的数据,并且其他事务每对该数据进行一次修改并提交后,该事务都能查询得到最新值。【即:可重复读】
3. 幻读
概述:事务a读取,事务b插入
针对三宗罪的隔离级别:
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 …. ;
#### 注意:涵盖增删改查的意思是,增删改时会记录mvcc的版本,查时不用for update
悲观锁,需要手动加,例如:
select * from table where ? lock in share mode;
select * from table where ? for update;
在一个事务里,如果对某条记录的查询操作加了上述的写锁,则当前记录就只能在当前事务里被修改,即走了悲观锁机制,并其也需要维护mvcc信息,因为要始终支持乐观锁机制。
上述过程,适应于:对一条记录,先查出来,判断后,再修改的场景。
针对上述场景:
一方面,是为了保证查出来的数据是”当前读“而不是”快照读“,因为后者可能不是最近数据;
一方面,是为了防止其他的事务的修改;
所以,innoDB默认乐观锁mvcc,但可以手动走悲观锁机制,手动走悲观锁机制时也需要维护mvcc信息,因为要始终支持乐观锁机制。
参考:
https://juejin.cn/post/6844904096378404872 (个人备份地址:转:浅谈MySQL并发控制:隔离级别、锁与MVCC_wangfy_的博客-CSDN博客)
彻底搞懂 MySQL 事务的隔离级别-阿里云开发者社区 (个人备份地址:转:彻底搞懂 MySQL 事务的隔离级别_wangfy_的博客-CSDN博客)