核心内容摘要
重拾青春记忆,解锁Mop经典:猫扑Mop破解版,不止于怀旧
予枫个人主页 个人专栏: 《Java 从入门到起飞》《读研码农的干货日常》 Debug 这个世界Return 更好的自己引言事务隔离级别是数据库面试的高频考点也是保证数据一致性的核心基础。
不少开发者在实际开发中总会被脏读、幻读、不可重复读这三大异常问题搞得头大尤其对MySQL默认的RR可重复读级别如何规避幻读一知半解。
本文将从基础概念出发逐一拆解RU、RC、RR、Serializable四种隔离级别重点深挖RR级别解决幻读的底层逻辑让你从理论到实操彻底吃透事务隔离级别文章目录引言
事务基础ACID原则是什么
事务并发的3大异常问题
1 脏读Dirty Read
2 不可重复读Non-Repeatable Read
3 幻读Phantom Read
四种事务隔离级别详解
1 Read UncommittedRU读未提交
2 Read CommittedRC读已提交
3 Repeatable ReadRR可重复读
4 Serializable串行化
四种隔离级别对比
总结
结尾
总结
事务基础ACID原则是什么在聊事务隔离级别之前我们必须先明确事务的核心特性——ACID原则这是理解隔离级别的前提原子性Atomicity事务是一个不可分割的最小单位要么全部执行成功要么全部执行失败回滚不存在部分执行的情况。
比如转账操作扣款和到账必须同时成功或同时失败。
一致性Consistency事务执行前后数据库的数据完整性约束不会被破坏。
比如转账前A和B的总余额是1000转账后总余额依然是1000。
隔离性Isolation多个事务并发执行时一个事务的执行结果不会被其他事务干扰每个事务都感觉不到其他事务在并发执行。
持久性Durability事务执行成功后对数据库的修改是永久性的即使数据库发生故障数据也不会丢失。
提示隔离性是本文的核心重点而事务隔离级别正是为了控制隔离性的强弱平衡并发性能和数据一致性。
事务并发的3大异常问题多个事务并发执行时如果没有合适的隔离机制就会出现以下3种异常情况这也是隔离级别需要解决的核心痛点
1 脏读Dirty Read定义一个事务读取到了另一个事务尚未提交的修改数据。
场景示例事务A执行转账操作给用户B扣款100元未提交事务B查询自己的余额读取到了扣款后的余额少了100元事务A因为异常回滚扣款操作失效事务B读取到的“少100元”的数据就是脏数据这就是脏读。
⚠️ 危害脏读会导致数据判断错误进而引发业务逻辑异常。
2 不可重复读Non-Repeatable Read定义同一个事务内多次读取同一批数据结果却不一致被其他事务修改并提交了。
场景示例事务A第一次查询用户B的余额结果为1000元事务B修改了用户B的余额为1500元并提交事务事务A再次查询用户B的余额结果变为1500元两次读取结果不一致。
注意不可重复读的核心是“修改”同一事务内读取到了其他事务提交的修改数据。
3 幻读Phantom Read定义同一个事务内多次执行同一查询语句返回的结果集行数不一致被其他事务插入或删除并提交了。
场景示例事务A查询余额大于500元的用户返回2条记录事务B插入了一条余额600元的用户记录并提交事务事务A再次执行相同的查询返回3条记录多了一条“幻影”数据。
✨ 关键幻读的核心是“新增/删除”同一事务内读取到了其他事务提交的新增/删除数据这也是最难解决的异常之一。
四种事务隔离级别详解为了解决上述并发异常问题SQL标准定义了四种事务隔离级别从低到高依次为Read UncommittedRU、Read CommittedRC、Repeatable ReadRR、Serializable串行化。
隔离级别越高数据一致性越强但并发性能越差。
1 Read UncommittedRU读未提交隔离级别最低允许读取其他事务未提交的数据。
解决异常不解决任何异常会出现脏读、不可重复读、幻读。
适用场景对数据一致性要求极低追求极致并发性能的场景几乎不用。
MySQL实操-- 设置隔离级别为读未提交SETSESSIONTRANSACTIONISOLATIONLEVELREADUNCOMMITTED;-- 开启事务STARTTRANSACTION;
2 Read CommittedRC读已提交隔离级别次低只允许读取其他事务已提交的数据。
解决异常解决脏读会出现不可重复读、幻读。
适用场景对数据一致性有一定要求允许不可重复读的场景如普通业务查询。
特点大多数数据库的默认隔离级别如Oracle、SQL Server但不是MySQL的。
MySQL实操-- 设置隔离级别为读已提交SETSESSIONTRANSACTIONISOLATIONLEVELREADCOMMITTED;STARTTRANSACTION;
3 Repeatable ReadRR可重复读隔离级别中高保证同一事务内多次读取同一批数据的结果一致。
解决异常解决脏读、不可重复读大部分幻读MySQL的RR级别特殊优化。
适用场景对数据一致性要求较高需要避免不可重复读的场景MySQL默认隔离级别。
核心重点MySQL RR级别如何解决大部分幻读MySQL的RR级别并没有完全遵循SQL标准而是通过MVCC多版本并发控制 间隙锁Gap Lock组合机制解决了大部分幻读问题MVCC机制事务开启时会生成一个一致性视图read view后续查询都会基于这个视图读取数据即使其他事务插入了新数据也不会被当前事务读取到从而避免了大部分幻读场景。
间隙锁当执行带有范围条件的查询如WHERE id 10时MySQL会在查询范围的间隙上添加锁阻止其他事务在该间隙内插入数据从根源上杜绝幻读。
MySQL实操-- 设置隔离级别为可重复读MySQL默认可省略SETSESSIONTRANSACTIONISOLATIONLEVELREPEATABLEREAD;STARTTRANSACTION; 建议如果觉得这部分RR级别的底层逻辑讲得清晰欢迎点赞收藏方便后续复习
4 Serializable串行化隔离级别最高强制所有事务串行执行不允许并发。
解决异常解决脏读、不可重复读、幻读所有异常。
适用场景对数据一致性要求极高不允许任何并发异常的场景如金融核心交易。
缺点并发性能极差会导致大量事务阻塞一般不推荐使用。
MySQL实操-- 设置隔离级别为串行化SETSESSIONTRANSACTIONISOLATIONLEVELSERIALIZABLE;STARTTRANSACTION;
四种隔离级别对比
总结为了方便大家快速对比和记忆整理了以下表格隔离级别脏读不可重复读幻读并发性能适用场景读未提交RU存在存在存在最高极少使用读已提交RC不存在存在存在较高普通业务查询可重复读RR不存在不存在大部分解决中等MySQL默认多数业务场景串行化Serializable不存在不存在不存在最低金融核心等强一致性场景
结尾
总结本文从事务ACID原则出发拆解了事务并发的3大异常问题脏读、不可重复读、幻读详细讲解了四种事务隔离级别的特性、适用场景及MySQL实操并重点分析了MySQL默认RR级别通过MVCC间隙锁解决大部分幻读的底层逻辑。
核心结论MySQL的RR级别是兼顾数据一致性和并发性能的最优选择能满足大部分业务场景的需求如果对一致性要求极高可选择串行化但需接受并发性能的损耗。