事务隔离级别需按场景精准选择:REPEATABLE READ防不住库存扣减中的幻读,SERIALIZABLE性能差,READ COMMITTED仍可能触发间隙锁;应优先用SELECT ... FOR UPDATE显式加锁,并配合唯一约束+重试处理幻读。事务隔离级别选错,脏读幻读不是bug是配置MySQL 默认的 REPEATABLE READ 看似稳妥,但对"库存扣减+下单"这类强一致性场景,它防不住幻读------比如两个事务同时查到库存 10,都通过校验,然后都执行 UPDATE inventory SET stock = stock - 1,结果变成 8 而非预期的 9。这不是代码写错了,是隔离级别没压住并发语义。真正起作用的不是"设得高",而是"设得准":READ UNCOMMITTED 基本不用,连未提交变更都能读,业务逻辑大概率崩READ COMMITTED 能防脏读,适合日志归档、报表统计等允许"读到中间态"的场景;但在库存类操作中,两次 SELECT 可能返回不同结果,导致校验失效REPEATABLE READ 是 InnoDB 默认,可重复读,但幻读靠间隙锁(gap lock)模拟,一不小心就锁表或死锁SERIALIZABLE 最严,所有 SELECT 隐式加共享锁,写操作阻塞读,吞吐暴跌,仅适合极低频关键核对(如财务对账)用 SELECT ... FOR UPDATE 而不是单纯调高隔离级别很多人以为把隔离级别提到 SERIALIZABLE 就万事大吉,其实更可靠、更轻量的做法是在关键路径显式加锁。比如扣库存前,用 SELECT stock FROM inventory WHERE id = 123 FOR UPDATE,这条语句会在索引记录上加行锁(如果条件走索引),后续同 key 的更新必须等待。注意几个实际坑点:没走索引?FOR UPDATE 会升级为表锁,整个表卡住WHERE 条件含函数或隐式转换(如 WHERE sku_id = '123' 但字段是 INT),索引失效,照样锁全表事务里先 SELECT ... FOR UPDATE,再做其他无关查询,可能延长锁持有时间,增加冲突概率应用层没捕获 Lock wait timeout exceeded 错误,直接报 500,用户感知就是"下单失败",而非重试幻读真实发生时,别硬扛,换唯一约束+重试比如"防止重复下单",用 SELECT ... FOR UPDATE 查订单是否存在,再插入,看似闭环,但两个事务查完都没单,都去插,唯一索引冲突后一个失败------这就是幻读在作祟。这时靠隔离级别解决成本高(SERIALIZABLE 太重),靠锁又难覆盖所有路径。 Murf AI AI文本转语音生成工具
相关推荐
Adios7941 小时前
VPR:Pitts50K和Norland数据集下载东风破1371 小时前
DM用户权限、表、约束等对象的基本操作,SQL日志的开启介绍收获不止数据库1 小时前
达梦9发布会归来:AI 时代,我们需要一款什么样的数据库?小宇的天下2 小时前
Virtuoso GUI 界面中的关键模块定义我的xiaodoujiao2 小时前
API 接口自动化测试详细图文教程学习系列16--项目实战演练3bqq198610262 小时前
MySQL 5.7 与 MySQL 8.0 的主要区别ID_180079054732 小时前
Python 实现亚马逊商品详情 API 数据准确性校验(极简可用 + JSON 参考)时空系2 小时前
第10篇:继承扩展——面向对象编程进阶 python中文编程Elastic 中国社区官方博客3 小时前
Elastic-caveman : 在不损失 Elastic 最佳效果的情况下,将 AI 响应 tokens 减少64%