Mysql数据库有四种隔离级别,read-uncommitted
, read-committed
,repeatable-read
和serializable
解决事务并发的脏读
, 不可重复读
以及幻读
的问题。
脏读: 在一个事务中读取到其他事务未提交的数据
不可重复读: 在一个事务中,两次读取数据不一致(更新和删除)
幻读: 在事务两次读取数据的过程中,其他的事务插入了新的数据,导致两次读取的数据数量不一致(增加)
幻读和不可重复读最大的区别在于解决问题使用的锁机制不同,不可重复读使用的是行锁, 幻读需要使用区间锁和NextKey-Lock
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交(read-uncommitted) | 会 | 会 | 会 |
读已提交(read-committed) | 不会 | 会 | 会 |
可重复读(repeatable-read) | 不会 | 不会 | 会 |
串行化(Serializable) | 不会 | 不会 | 不会 |
读未提交: 可以读取其他事务未提交的数据,当其他事务失败,数据回滚,就会导致脏读
读已提交: 读取最新的镜像数据, 事务A在读取数据之后(未加锁),事务B对相关数据更新或者删除并且顺利提交之后,事务A会读取最新的数据,导致两次数据读取不一致,引起不可重复读问题
可重复读: 事务A读取当前的事务A当前的镜像,事务B对数据更新、删除、插入之后,事务A依然读取事务A当前镜像,所以可以避免不可重复读问题。(问题: 为什么还存在幻读问题??)
串行化: 事务A在结束之前,事务B不会开始执行,所以不会导致任何并发问题。
MVCC(多版本并发控制)
原理: 在数据行添加隐藏的两列创建版本号和删除版本号,每一个一次修改都会生成一个自增的版本号。
所以在查询时需要查询符合版本条件的数据create_version <= current_version < delete_version