我正在编写一个 PHP 函数,用于将大量数据存储/更新到表中,这可能会导致死锁。我尝试研究如何使用 Doctrine 重试失败的交易,但遗憾的是在网上找不到任何信息。我最终写了下面的代码
$retry = 0;
$done = false;
while (!$done and $retry < 3) {
try {
$this->entityManager->flush();
$done = true;
} catch (\Exception $e) {
sleep(1);
$retry++;
}
}
if ($retry == 3) {
throw new Exception(
"[Exception: MySQL Deadlock] Too many people accessing the server at the same time. Try again in few minutes"
);
}
我的问题:这种方法是否有可能在数据库中插入重复项?如果是这样,我如何强制 Doctrine 回滚交易?
最佳答案
死锁返回错误 1213,您应该在客户端处理该错误
请注意,死锁和锁等待是不同的东西。在僵局中,没有“失败”的交易:他们都有罪。无法保证会回滚哪一个。
您必须使用rollback
,您的样式代码将插入重复项。例如你应该:
$retry = 0;
$done = false;
$this->entityManager->getConnection()->beginTransaction(); // suspend auto-commit
while (!$done and $retry < 3) {
try {
$this->entityManager->flush();
$this->entityManager->getConnection()->commit(); // commit if succesfull
$done = true;
} catch (\Exception $e) {
$this->entityManager->getConnection()->rollback(); // transaction marked for rollback only
$retry++;
}
}
希望这对您有所帮助。
关于php - 如何使用 Doctrine 在死锁后重试事务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13069315/