程序员面试宝典之Mysql数据库Innodb引擎的4个隔离级别

这就是危险:MySQL默认的隔离级别不是“已提交读”而是“可重复读”。

这就是危险:高隔离级别(例如可重复读)很容易导致幻读并影响操作。

实用提醒:测试数据库隔离级别对业务的影响,保证数据一致性。

示例MySQL事务隔离级别以及脏读、幻读、不可重复读

说实话,以前在谈到MySQL事务隔离时,我都觉得相当混乱,但是现在了解了几个概念,我的感觉就好多了。
你提到的四个级别,每一个级别都必须与实际场景相对应,这样才容易理解。

首先我们来说说脏读,这个很容易理解。
我以前在电商系统中也遇到过这种情况。
后端设置了定时任务处理优惠券,但是代码错误没有锁定。
结果,线程A只是将用户优惠券的状态更改为“已使用”,但尚未提交。
然后线程B发现优惠券状态尚未提交。
最终,用户刷卡又收到了一张不该收到的优惠券。
这就是典型的脏读——读别人半成品的数据。
这就是在 SQL 标准中读取未提交数据时所做的事情。
它是完全开放的,所有人都可以看到。

有趣的是它不能重复阅读。
我在做报表统计的时候遇到了陷阱。
会话 A 检查特定产品的销量是否为 1 00 件。
结果B会话在下一笔交易中疯狂促销。
1 0分钟后A再次查看,销量突然变成了2 00台。
这种情况不会发生在“读已提交”级别,但可能会发生在未提交读和可重复读的情况下。
就像你刚拍了一张照片,你的手机就被别人碰了。
如果你拍一张新照片,情况就会有所不同。

幻读是最微妙的。
曾经,我们的系统使用可重复读取来搜索特定价格范围内的产品。
第一次我们发现了 3 个产品,几分钟后我们再次检查,突然又发现了 5 个相同价格范围的产品,因为又插入了一个线程。
这和不可重复读的区别在于,不可重复读意味着数据值被改变,而幻读意味着记录被添加或删除。
我已经测试过,MySQL InnoDB 实际上可以通过在可重复读级别使用 Next-Key 锁来防止幻读,这比 SQL 标准更细粒度。

说到连载,不得不提一个现实问题。
这是一个必须重建的支付系统。
旧系统使用read-commit,新系统直接序列化。
结果,测试环境中CPU爆炸了——因为序列化会将并发请求变成串行处理。
但在一致性强的场景下,比如电汇,这确实是唯一的方法。
我建议你在使用这个级别之前先测试一下你能下降多少TPS。

我记得数据是关于X的,但是我建议你检查一下InnoDB的可重复读取和序列化的具体锁定机制。
我个人没有在这方面运行过分布式事务,但是在独立测试过程中我发现序列化过程中读写锁的粒度控制尤为关键。
当发生写写冲突时,延迟可以达到秒级。

mysql默认事务隔离级别有哪些

等等,昨晚调试订单系统时遇到了奇怪的事情。
用户A刚刚下单,数据尚未同步。
用户B找到了订单详情。
我很快进入日志模式,发现隔离级别有问题。
ReadUncommitd,这玩意简直就是数据混乱的温床,想想就恐怖。
不过,仓库经理张先生表示,使用 ReadCommit 的效率要高得多,偶尔看到其他订单的变化也不会造成任何影响。
他办公室的旧电脑屏幕几乎烧坏了,但他仍在运行 MySQL 5 .7 版本。