php - 如何使用 Doctrine 在死锁后重试事务?

标签 php mysql database doctrine-orm deadlock

我正在编写一个 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/

相关文章:

sql - 对于这个特定的数据库设计问题,您会使用哪种方法?

PHP 自动套用段落格式标签

javascript - 如何使用 php 代理将站点加载到 iframe 中?

mysql - MySQL表中累计到差分数据

c# - 从新类访问数据集和表适配器

mysql - 从 phpMyAdmin 中找出 MySQL 数据库 URL

php - 嵌套动态 PHP 类

php - 使用php创建上传字段并将url发送到数据库

mysql - 按计数和时间戳对 mysql 数据进行排序

php - 使用 mysql 和 php 进入文本区域并返回的脚本