3

私は現在のセットアップを持っています:

通常の Symfony2 Web リクエストは、 GearmanジョブJobも作成するエンティティを作成および保持できます。これが で発生するとします。ギアマン ジョブは、エンティティのを渡されたギアマン ワーカーによって実行されます。process 1JobID

また、Symfony を使用して Gearman Worker を作成します。これは PHP CLI プロセスとして実行され、これを呼び出しますprocess 2

Gearman に慣れていない人のために説明すると、ワーカー コードは次のように動作します。

for loop 5 times
    get job from gearman (blocking method call)
    get job entity from database
    do stuff

基本的に、このコードは Symfony2 インスタンスを実行し続け、ワーカーが終了するまで 5 つのジョブを処理します。

私の問題は次のとおりです。ワーカーが処理する最初のジョブで、Doctrine2 は次のコードを使用して問題なくデータベースから作成されたジョブを取得できます。

$job = $this->doctrine
            ->getRepository('AcmeJobBundle:Job')
            ->findOneById($job->workload()); // workload is the job id

ただし、このジョブが完了し、for ループがインクリメントして 2 番目のジョブを待機すると、 with 2process 3の作成時に別の Symfony2 Web リクエストからこれが到着したとします。エンティティが確実にデータベースにある場合でも、Doctrine2 リポジトリへの呼び出しは null を返します。 .JobID

ワーカーを再起動すると問題が解決するため、最初のループを実行するとJob2 を取得できます。

なぜこれが起こるのか誰か知っていますか?最初の呼び出しは、MySQL から何らかのテーブル キャッシングを行うgetRepositoryfindOneById、その後追加される 2 を認識できないようにしますJobか?

MySQL は、特定の接続が開いている限り、DB のスナップショットのみを表示しますか?

entityManagerまた、2回目の呼び出しをfindOneBy無駄にする前に、をリセットしようとしました。

事前にアドバイスをありがとう、これは本当に私を困惑させています.

アップデート:

問題の原因が同時実行性であるかどうかを除外するために単一プロセスのテスト ケースを作成しました。テスト ケースは期待どおりに実行されます。リポジトリがジョブ 2 を見つけられないのは、別のプロセスで DB に追加されたときだけのようです。

    // Job 1 already exists
    $job = $this->doctrine
    ->getRepository('AcmeJobBundle:Job')
    ->findOneById(1);

    $job->getId(); // this is fine.

    $em->persist(new Job()); // creates job 2

    $em->flush();

    $job = $this->doctrine
    ->getRepository('AcmeJobBundle:Job')
    ->findOneById(2);

    $job->getId(); // this is fine too, no exception.
4

1 に答える 1

1

おそらく、1 つのプロセスが、2 番目のプロセスによってエンティティが保存される前にエンティティをロードしようとします。

Doctrine はロードされたエンティティを ID でキャッシュするため、同じオブジェクトに対する 2 番目のリクエストを受け取ると、データベースに別のクエリを作成することなくロードされます。Doctrine IdentityMap の詳細については、こちらを参照してください。

于 2013-04-27T11:21:39.567 に答える