通过PHP进行MySQL死锁检测

clo*_*ops 1 php mysql transactions

在PHP中处理MySQL死锁的最佳做法是什么?我应该在try {} catch {}块中包装所有数据库调用,并从数据库中查找DeadLock错误代码吗?然后我再次重新发出整个交易(我认为那个易于回滚的交易)?

Qua*_*noi 5

死锁返回错误1213,您应该在客户端处理该错误

请注意,死锁和锁定等待是不同的事情.陷入僵局,没有"失败"的交易:他们都有罪.无法保证哪一个将被回滚.

在这样的场景中发生死锁:

UPDATE  t_first -- transacion 1 locks t_first
SET     id = 1;

UPDATE  t_second -- transaction 2 locks t_second
SET     id = 2;

UPDATE  t_second -- transaction 1 waits for transaction 2 to release the lock on t_second
SET     id = 2;

UPDATE  t_first -- transaction 2 waits for transaction 1 to release the lock on t_first. DEADLOCK
SET     id = 2;
Run Code Online (Sandbox Code Playgroud)

你确定你没有把它与锁等待混淆吗?

只要事务尝试锁定已被另一个事务锁定的资源,就会发生锁定等待.

在上面的示例中,在步骤中发生锁定等待3.

由于这是正常情况(与死锁不同),可以通过提交或回滚持有锁的事务从外部解析,InnoDB因此不会尝试回滚持有锁的事务.

相反,它只会取消在超时发生后尝试获取锁定的语句.

默认情况下,超时为50秒,并使用设置innodb_lock_wait_timeout.

失败的语句(试图获取锁定的语句)将返回错误1205.