数据库错误:
[ error ] [10501]SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction
InnoDB的行锁和解锁都是针对主键索引的,如果查询(SELECT)时根据索引锁表,但更新(UPDATE)时却不是通过主键更新,那么等待解锁查询的进程将会报1213错误,程序可能返回一个NULL值。
错误排查,执行SHOW ENGINE INNODB STATUS
命令已获取INNODB引擎当前状态信息,其中LAST DETECTED DEADLOCK
记录着最近一次的死锁信息。
$ SHOW ENGINE INNODB STATUS;
同时可结合查询数据库内置表information_scheme
库中的INNODB_TRX
、INNODB_LOCKS
、INNODB_LOCK_WAIT
三张表,获取事务的状态信息。
死锁发生需要满足两个条件
- 至少有两个请求同时在执行同一个事务
- 请求1锁定某一行且未提交事务,与此同时请求2也需要
update/delete
这一行,此时请求2会进入锁等待(LOCK WAIT)状态,直到出现死锁(DEAD LOCK)。
死锁出现场景
事务A在等待事务B释放的行锁,而事务B在等待事务A释放的行锁,事务A和事务B在相互等待对方的资源释放就进入了死锁状态。
如何减少死锁的发生概率呢?
- 事务操作锁定的行数要越少,以及更加精确的索引条件。
- 保证事务具有较短的执行时间,执行完后立即提交。
网友评论