首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于PHP的MySQL死锁检测

基于PHP的MySQL死锁检测
EN

Stack Overflow用户
提问于 2009-10-12 12:58:07
回答 2查看 5.5K关注 0票数 1

在PHP中处理MySQL死锁的最佳实践是什么?我是否应该将所有数据库调用包装在try{}catch{}块中,并从数据库中查找DeadLock错误代码?然后,我是否再次重新发布整个事务(我假设失败的事务已回滚)?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-10-12 13:07:05

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

请注意,死锁和锁等待是不同的事情。在死锁中,没有“失败”的事务:它们都是有罪的。不能保证哪一个会被回滚。

死锁发生在如下场景中:

代码语言:javascript
复制
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不会尝试回滚持有锁的事务。

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

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

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

票数 5
EN

Stack Overflow用户

发布于 2015-08-03 05:45:38

我想引用MySQL的How to Cope with Deadlocks中的这些温暖的话。

如果事务由于死锁而失败,

总是准备好重新发出事务。死锁并不危险。再试一次。

这可以通过这样的模式来实现:

代码语言:javascript
复制
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;
        }
    }
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1554432

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档