在PHP中处理MySQL死锁的最佳实践是什么?我是否应该将所有数据库调用包装在try{}catch{}块中,并从数据库中查找DeadLock错误代码?然后,我是否再次重新发布整个事务(我假设失败的事务已回滚)?
发布于 2009-10-12 13:07:05
死锁返回错误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不会尝试回滚持有锁的事务。
相反,它只会取消在超时发生后试图获取锁的语句。
默认情况下,使用innodb_lock_wait_timeout设置超时时间为50秒。
失败的语句(试图获取锁的语句)将返回错误1205。
发布于 2015-08-03 05:45:38
我想引用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;
}
}
}https://stackoverflow.com/questions/1554432
复制相似问题