在PHP中处理MySQL死锁的最佳做法是什么?我是否应该将所有数据库调用都封装在try {} catch {}块中,并从数据库中查找DeadLock错误代码?然后我是否再次重新发布整个交易(我认为失败的回滚)?通过PHP检测MySQL死锁
1
A
回答
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;
你确定你不锁等待混淆呢?
只要事务尝试锁定已被另一个事务锁定的资源,就会发生锁定等待。
在上面的示例中,在步骤3
上发生锁定等待。
由于这是一种正常情况(不像死锁),可以通过提交或回滚持有锁的事务从外部解决,因此InnoDB
不会尝试回滚持有该锁的事务。
取而代之,它将取消在超时发生后尝试获取锁的语句。
默认的超时时间为50
秒,使用innodb_lock_wait_timeout
进行设置。
失败的语句(试图通过获取的锁)将返回错误1205
。
3
我想从这些引用温暖的话语MySQL的How to Cope with Deadlocks
常作准备,如果它因为死锁而失败重新发出一个事务。僵局并不危险。再试一次。
这可以通过这样的方式来实现:
for ($i = 3; true; $i--) {
$pdo->beginTransaction();
try {
// Do the unit of work
$pdo->commit();
break;
} catch (\PDOException $e) {
$pdo->rollback();
if ($i <= 0) {
throw $e;
}
}
}
相关问题
- 1. Mysql死锁检测
- 2. MySql:事务不检测死锁?
- 3. 通过PHP检测MySQL InnoDB
- 4. 锁树算法死锁检测
- 5. 如何检测Asio库的死锁?
- 6. 使用JVMTI进行死锁检测
- 7. 如何检测Django中的死锁?
- 8. 疑难解答aspnet_isapi.dll检测到死锁
- 9. 麻烦实施死锁检测算法
- 10. mysql事务死锁
- 11. 通过php mysql的行锁定
- 12. 由于Pragma自主事务过程而检测到死锁
- 13. 通过PHP的PHP cron检测?
- 14. grails服务与MySQL锁死
- 15. MySQL的死锁某些列
- 16. mysql死锁解决方案〜
- 17. Spring JPA + MySQL和死锁
- 18. Mysql所有死锁日志
- 19. 在MySQL中获取死锁
- 20. Mysql select ...更新死锁
- 21. 如何避免mysql死锁?
- 22. 需要Mysql死锁解释
- 23. 死锁预防(Java + MySQL)
- 24. 插入Mysql的死锁
- 25. x单元测试死锁
- 26. 使用nUnit测试死锁
- 27. 死锁线程检查
- 28. 通过使用锁来说明死锁的示例代码(this)
- 29. 了解走通道死锁
- 30. Java Socket通信“死锁”
@RomanNewaza:因为交易双方锁定两个表,尽管在不同的顺序。 – Quassnoi 2013-01-29 07:27:52
是的,我明白了。谢谢! – 2013-01-29 07:53:09