read committed 是多数业务的合理起点,它避免脏读且不默认加间隙锁,而 mysql 的 repeatable read 会因间隙锁导致并发阻塞,postgresql 同名级别实为无锁快照隔离。

事务隔离级别怎么选才不拖慢查询
不同隔离级别直接影响锁的粒度和持有时间。READ COMMITTED 是多数业务的合理起点,它避免脏读,又不像 REPEATABLE READ 那样在 MySQL 中默认加间隙锁(Gap Lock),导致 UPDATE 范围扩大、并发阻塞变多。PostgreSQL 的 REPEATABLE READ 实际是快照隔离,不加锁,但 MySQL 不是——这点常被忽略。
-
READ UNCOMMITTED基本不用:读未提交数据可能引发业务逻辑错乱,比如扣款前看到未确认的余额 -
SERIALIZABLE会把很多 SELECT 变成锁读,高并发下极易出现Lock wait timeout exceeded - 如果只是防止幻读且不想锁太多,用
SELECT ... FOR UPDATE显式加锁比盲目升隔离级别更可控
FOR UPDATE 和 LOCK IN SHARE MODE 的实际差异
FOR UPDATE 加的是排他锁(X 锁),阻止其他事务读写;LOCK IN SHARE MODE 加的是共享锁(S 锁),允许其他事务加 S 锁但拒绝 X 锁。关键不是“能不能读”,而是“别人还能不能改”。
- 在更新前校验库存时,用
SELECT stock FROM items WHERE id = 123 FOR UPDATE,能确保后续UPDATE不会覆盖并发修改 - 若只做只读校验(如判断用户是否已投票),
LOCK IN SHARE MODE可降低冲突概率,但注意:MySQL 8.0+ 对二级索引加 S 锁时,仍可能触发聚簇索引上的隐式锁升级 - 不带
WHERE条件的SELECT ... FOR UPDATE会锁全表,生产环境务必避免
死锁日志里怎么看谁抢了哪把锁
MySQL 的 SHOW ENGINE INNODB STATUS 输出中,<strong><em> (1) WAITING FOR THIS LOCK TO BE GRANTED:</em></strong> 下面那行就是当前事务卡住的锁请求; (2) HOLDS THE LOCK(S): 后面列出的是另一个事务持有的锁。
websenB2B是一套经过完善设计的B2B行业网站程序,是windows nt系列环境下最佳的B2B行业网产站解决方案。精心设计的架构与功能机制,适合从个人到企业各方面应用的要求,为您提供一个安全、稳定、高效、易用而快捷的行业网站商务系统。分普及版和商业版等不同版本。一、网胜B2B电子商务系统SP6.2蓝色风格普及版本升级功能说明:1、邮件群发功能:可以选择某一级别的会员,并放入支持html
- 注意锁对象格式:
record lock, heap no 123表示某行记录锁,gap before rec是间隙锁,supremum pseudo-record意味着锁住了索引区间上限 - 死锁通常发生在两个事务以不同顺序访问相同索引行,比如事务 A 先锁
id=10再锁id=20,事务 B 反过来——修复方式不是加重试,而是统一 SQL 访问顺序(如总是按id ASC排序后处理) -
innodb_print_all_deadlocks = ON必须开,否则只记录最近一次,线上排查基本靠猜
长事务为什么让主从延迟飙升
长事务本身不直接导致延迟,但它会让 binlog 事件迟迟不落盘,同时阻塞 purge 线程清理 undo log,进而拖慢从库的 relay log 回放速度。更隐蔽的问题是:它让 MVCC 版本链拉得极长,SELECT 扫描时要跳过大量已删除但未 purge 的版本。
-
information_schema.INNODB_TRX里查TRX_STARTED和TRX_ROWS_LOCKED,能快速定位“睡着还占着锁”的事务 - 应用层设置
wait_timeout和interactive_timeout防连接空闲挂起,但更重要的是业务代码里别用一个事务包着 HTTP 请求全过程 - 使用
SELECT ... FOR UPDATE NOWAIT可避免无限等待,捕获Lock wait timeout exceeded后主动降级或重试,而不是让事务僵死几分钟
事务的复杂点不在语法,而在锁如何随索引结构、隔离级别、执行路径动态变化。同一个 UPDATE 语句,在有无索引、是否走范围条件、是否涉及外键约束时,锁的类型和范围可能完全不同——查执行计划不够,得看 INNODB_STATUS 里的真实锁信息。









