多线程批量新增更新死锁场景 (结论:批量更新建议使用id进行更新)
共有10个线程,每次处理200个数据
表中有一个主键,和普通索引。
- 场景1
多线程进行新增和更新操作,更新时通过普通索引键进行更新
结论:发生死锁
- 场景2
多线程进行新增和更新操作,更新时通过主键进行更新
结论:不会死锁
- 场景3
多线程进行新增或多线程进行更新操作。
结论:不会死锁。
多线程批量新增死锁场景;
共有10个线程,每个线程一次新增200条数据。
-
场景1
表中有一个主键和一些普通二级索引(非唯一索引).
主键值为雪花算法生成,每次生成的值,一定是表里最大值。
结论:不会死锁 -
场景2
表中有一个主键和一些普通二级索引(非唯一索引).
主键值为其他方式生成,且每次生成的值,随机分布在表中id的任意区间。
结论:主键死锁
-
场景3
表中有一个主键和一个唯一索引
主键值为雪花算法生成,且每次生成的值,一定是表里最大值。
唯一索引字段值为其他方式生成,且每次生成的值,随机分布在表中此字段的任意区间
结论:唯一索引字段死锁 -
原因;结论待验证
某一Thread优先执行insert,由于存在唯一字段,需要校验唯一性,需要先加锁(防止值发生变更),加锁时,如果能找到该索引值,就加记录锁(只锁定此索引),若不能找到,则锁定最近的两个索引区间。
场景2/3,每次insert会有200条数据,最多可能会锁住200个区间,多个事务就可能存在死锁冲突。
场景1,每次insert第一次扫描的区间一定是:表中最大值的索引->无穷大。也就防止了其他事务加锁的可能性。
网友评论