其他
一个线上SQL死锁异常分析:深入了解事务和锁
阿里妹导读:引发死锁的原因是什么?如何避免?本文详细介绍了和死锁有关的知识点,通过深入分析MySQL事务和锁的机制,结合案例背景,找到了问题的所在,并梳理了解决方案,详解其原理。希望对同学们有所启发。
原子性(Atomicity):事务内SQL要么同时成功要么同时失败 ,基于UndoLog实现。
一致性(Consistency):系统从一个正确态转移到另一个正确态,由应用通过AID来保证,并非数据库的责任。
隔离性(Isolation):控制事务并发执行时数据的可见性,基于锁和MVCC实现。
持久性(Durability):提交后一定存储成功不会丢失,基于RedoLog实现。
UPDATE students SET score = 100 WHERE id = 15;
UPDATE students SET score = 100 WHERE id = 16;
UPDATE students SET score = 100 WHERE no = 'S0003';
UPDATE students SET score = 100 WHERE no = 'S0008';
UPDATE students SET score = 100 WHERE name = 'Tom';
https://zhuanlan.zhihu.com/p/245584417
为了防止幻读,如果记录之间加有GAP锁,此时不能INSERT。
如果INSERT的记录和已有记录造成唯一键冲突,此时不能INSERT。
delete from db.table where creativeid=102(且删除条数为0)
delete fromdb.tablewhere creativeid=103(且删除条数为0)
insert intodb.table (creativeid) values (102)
insert intodb.table (creativeid) values (103)
降低隔离级别为RC,避免间隙锁(降级后会有不可重复读和幻读问题)。
设置InnoDB在RR级别下不使用间隙锁(关闭后会有幻读问题)。
删除前先判断是否存在,存在再删除,可以完全避免死锁(会导致重复数据录入)。
方案1:select for update(会降低并发度)。
方案2:加唯一索引,捕获异常回滚不执行。
方案3:若允许极端少数重复数据(仅文案展示),则无需处理。
假设表中不存在2和5对应记录,只有1和6
假设表中2和5都存在
假设表中2存在