场景:
对于mysql,当使用InnoDB做引擎时。如果update语句的where条件不是主键索引(聚簇索引),而是使用非主键索引时,会先锁住当前非主键索引,然后再尝试获取主键索引的锁; 如果事务一: 已经锁住id =1 这一行的主键索引和 id = 2这一行的非主键索引,尝试去获取id=2的主键索引的锁; 事务二: 已经锁住id =2 这一行的主键索引和 id = 1这一行的非主键索引,尝试去锁住id=1这一行的主键索引。两个事务操作出现相互等待资源的循环,也就是死锁。
解决方式:
在一个事务里面,需要update的时候,先select出所有需要更新的记录的主键,然后再进行update,where条件只用主键。所有update语句将会只锁住主键索引,而不会尝试锁非主键索引。
批注: 我这里讲的是如何避免这种死锁,如果不想用悲观锁,可以参考我另一篇文章: https://www.jianshu.com/p/40a875d6e471