上一篇
2025年7月最新动态:
近期MySQL 8.3版本优化了InnoDB引擎的锁机制,官方文档特别强调悲观锁在特定场景下的读取行为可能受事务隔离级别影响,开发者社区热议「是否所有悲观锁都会彻底阻塞读取」成为高频技术话题。
悲观锁(Pessimistic Lock)就像个「被害妄想症患者」——它默认并发操作一定会冲突,所以只要抢到锁就死死抱住不撒手,直到事务结束,MySQL中典型的悲观锁实现包括:
SELECT ... FOR UPDATE
(写锁) SELECT ... LOCK IN SHARE MODE
(读锁,已逐渐被淘汰) 「悲观锁下能否读取数据」的本质其实是:
-- 事务A BEGIN; SELECT * FROM accounts WHERE id=1 FOR UPDATE; -- 加悲观锁 SELECT * FROM accounts WHERE id=1; -- 可以正常读到数据(甚至不需要COMMIT) COMMIT;
✅ :悲观锁不会阻塞当前事务的普通查询,因为锁本来就是你自己加的。
-- 事务A加锁 BEGIN; SELECT * FROM accounts WHERE id=1 FOR UPDATE; -- 事务B尝试读取(不同会话) SET TRANSACTION ISOLATION LEVEL READ COMMITTED; SELECT * FROM accounts WHERE id=1; -- 能读到旧数据!
✅ :RC级别下,其他事务的普通SELECT不受悲观锁影响(但读到的是锁前的快照)。
-- 事务A加锁(同上) -- 事务B设置RR级别 SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; SELECT * FROM accounts WHERE id=1; -- 依然能读到旧数据
✅ :RR级别表现与RC类似,但底层通过MVCC机制实现(读取视图版本不同)。
-- 事务A持有锁(同上) -- 事务B尝试加锁 SELECT * FROM accounts WHERE id=1 FOR UPDATE; -- 卡住直到超时!
❌ :只要其他事务想获取同一条记录的悲观锁,一定会被阻塞。
InnoDB默认所有普通SELECT都是快照读(Snapshot Read),它:
-- 错误示范:以为加了锁就能阻止别人读 SELECT * FROM orders WHERE status='pending' FOR UPDATE; -- 其他事务依然能看到pending订单(只是不能修改)
如果需要完全不可见的效果:
本文由 隆安翔 于2025-07-31发表在【云服务器提供商】,文中图片由(隆安翔)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://vps.7tqx.com/wenda/494906.html
发表评论