Mysql 死锁分析

1. 结论

  1. 死锁检查机制
    1. 当事务A需要获取一个行锁时(例如更新一行数据),假如需要获取行1的锁
      1. 检查其他事务有没有已获取了行1的锁。
      2. 如果有,例如事务B已获取了行1的锁。
      3. 继续检查事务B在等待的锁,如果有,而且是事务A已获取的锁(例如行2的锁)
      4. 事务A抛出异常:Deadlock found when trying to get lock; try restarting transaction
  2. 更新内容
    1. 获取锁后更新哪个字段,和锁是无关的。
    2. 例如事务A获取行1锁更新字段1,事务B获取行1锁更新字段2,虽然它们更新的字段不一样,但是锁是一样的,也会触发死锁。

2.实验

进程1

update test_table set key1=1 where id=1
sleep 10s
update test_table set key1=2 where id=2

进程2

update test_table set key2=1 where id=2
sleep 10s
update test_table set key2=2 where id=1

假如进程1先执行,1s后执行进程2,结果:

  • 进程1能成功commit
  • 进程2在第2个update时报错
  • 尽管2个进程update的字段不一样,但是因为where语句一样,mysql都是通过id主键索引来查询数据,所以是锁住了主键索引。
原文地址:https://www.cnblogs.com/Xjng/p/14958435.html