2

これが好ましい方法かどうかはわかりませんが、私の解決策を提示し、symfony2 ウィザードがこれについて啓発的なコメントを持っているかどうかを確認したいと思います。

テーブルに金融取引を登録していますが、各ユーザーには独自の一連のシリアル番号があります (つまり、各ユーザーの取引テーブルは 1 から始まります)。

これはコードで処理する必要があることを理解していますが、トランザクションを登録する同じユーザー アカウントに 2 人のユーザーがログオンしたり、ユーザーが複数のトランザクション書き込みを同時にトリガーしたりすると、ユーザーのエントリが重複するリスクがあります。時間とDoctrineは、最初の書き込みが発生する前に、両方の操作でSELECTを実行する必要がありました...

        $em->getConnection()->exec('LOCK TABLES transaction WRITE;'); //lock for write access

            $results = $em->createQuery("SELECT MAX(t.serial) FROM ekonomiKassabokBundle:Transaction t WHERE t.user = $userId")->getResult();
            $temp = $results[0];
            $max_serial = $temp[1];
            $new_serial = $max_serial + 1;

            $entity->setSerial($new_serial);

            $em->persist($entity);
            $em->flush();

        $em->getConnection()->exec('UNLOCK TABLES;');

上記のコードは私に与えます...

SQLSTATE[HY000]: General error: 1100 Table 't0_' was not locked with LOCK TABLES

それとも、これはやり過ぎかもしれません。テーブル ロックをスキップする必要がありますか?

4

1 に答える 1

3

私は最終的に解決策を見つけることができまし

実際、私が理解していることからすると、それはかなりばかげています。テーブルをロックすると、MySQL は、ロックが解除されるまで使用するすべてのテーブルを期待し、これは 1 つの LOCK TABLES ステートメントで発生する必要があります。

現在、Doctrine は何らかの理由で体系的にテーブル エイリアスを使用しており、MySQL はエイリアスがロックされたテーブルを参照していることを明らかに理解できません。

試す:

$em->getConnection()->exec('LOCK TABLES transaction as t0_ WRITE;');

この後に別のエラーが発生した場合 (テーブルがロックされている間に複数のクエリを実行すると発生します)、追加のエイリアスにロックを追加し続けます。たとえば、次のようになります。

$em->getConnection()->exec('LOCK TABLES transaction as t0_ WRITE, transaction as t0 WRITE, transaction as t1 WRITE;');

幸いなことに、Doctrine は常に同じテーブル エイリアスを使用しているようです。

于 2012-12-29T16:25:11.500 に答える