8

大量のデータ セットをテーブルに格納/更新する 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 にトランザクションをロールバックさせることができますか?

4

4 に答える 4

16

デッドロックによりエラー 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++;

    }

}

この助けを願っています。

于 2012-10-31T03:03:15.470 に答える
-5

ORM を使用していない場合は、デッドロック状況を自動的に管理することを使用してください。

于 2012-10-30T08:58:05.133 に答える