Mysql中事务的隔离级别以及实现原理
在mysql的InnoDB存储引擎下支持事务,其中事务级别主要有以下几种
一.事务隔离级别
1.读未提交
读未提交是mysql中最低的隔离级别,虽然执行速度快,但是不能解决并发问题。读未 提交允许一个事务读取另一个事务还未提交的数据,会造成脏读。
会出现脏读、不可重复读、幻读的问题
详见 脏读、幻读、不可重复读产生的原因及解决方案-CSDN博客
2.读已提交
读已提交,只允许读取事务已提交的数据,可以解决脏读的问题。
会出现不可重复读、幻读的问题
3.可重复读
可重复读是InnoDB默认的隔离级别,其保证了事务两次读取同一数据的一致性,解决了 不可重复读。
目前mysql优化了可重复读,利用锁机制可以解决大部分幻读问题
4.串行化(序列化)
所有操作串行化执行,可以解决脏读、幻读、不可重复读。并发能力最低
二.实现原理
Mysql通过MVCC(多版本并发控制)实现事务的隔离机制。其主要原理是在表中存在三个隐藏字段:“主键ID(不存在主键的情况)”、“事务ID”、“回滚指针”。在事务开启后读取数据时,会为其生成一个read View快照,其中记录着对应数据的事务id。当在并发环境下,事务可以按照依靠undo log实现的回滚指针来保证数据的一致性。
其中读未提交不使用MVCC机制,所有操作几乎不保证安全。读已提交可以依靠行锁或乐观锁实现。可重复读利用记录锁+间隙锁,锁住范围内数据,不允许插入,或者通过MVCC避免(读取事务开始时产生的快照),可以解决大部分问题。串行化则全部利用排他锁实现。
隔离级别 | MVCC 行为 | 锁机制 | 解决的异常 |
---|---|---|---|
Read Uncommitted(读未提交) | 不使用 MVCC | 无锁或最小化锁 | 无 |
Read Committed(读已提交) | 每次查询生成新 Read View | 行锁(仅当前记录) | 脏读 |
Repeatable Read(可重复读) | 事务首次生成 Read View | Next-Key Lock(记录+间隙锁) | 脏读、不可重复读、部分幻读 |
Serializable(串行化) | 禁用 MVCC,完全依赖锁 | 所有操作加锁 | 所有异常 |