7

コンテキストは次のとおりです。

  • プロデューサー(JTAトランザクションPT)は、JMSキューにメッセージを送信し、DBを更新しています。
  • コンシューマー(JTAトランザクションCT)は同じキューでリッスンし、メッセージを受信するとDBを読み取ります。
  • アプリケーションサーバー-WebLogic、DB-Oracle。

対応するJMSメッセージがすでに受信されている場合(PTがコミットされている場合)、CTがPTのDB変更を(まだ?)確認できない場合があることを確認しました。

JTAはそのような種類の一貫性を保証できないようです(これはJurgen Hollerのプレゼンテーション「TransactionChoicesforPerformance」でも確認されています)。

そのような問題を回避するための最良の方法は何ですか(明白な場合を除いて-JTAを使用しない)?

ありがとう。

4

3 に答える 3

4

したがって、そのためのシンプルでエレガントで失敗のないソリューションはないようです。私たちの場合、単純な再配信メカニズム(例外をスローし、一定時間後にJMSメッセージを再配信させる)に依存することにしました。

また考慮される:

  • DBデータソースをマークし、Last Resource Commit Optimization(LRCO)が開始されることを期待します(したがって、XAトランザクション内のコミットの順序を部分的に制御します)。アプリケーションサーバー(WL)の内部に依存しているため、拒否されました。

  • DeliveryDelayをJMSメッセージに設定します。これにより、(おそらく)DB同期が終了した後、しばらくしてからのみ使用できます。保証がなく、さまざまな環境に合わせて微調整する必要があるため、拒否されました。

他の回答で言及されているブログ投稿には、実際にこれらすべてとカバーされている他のいくつかのオプションが含まれています(ただし、決定的なものはありません)。

于 2013-02-07T17:42:34.253 に答える
1

いくつかのオプションの概要は次のとおりです:http: //jbossts.blogspot.co.uk/2011/04/messagingdatabase-race-conditions.html

于 2013-01-30T12:14:17.267 に答える
0

答えについて:

「そのため、そのためのシンプルでエレガントなフェイルプルーフソリューションはないようです。私たちの場合、単純な再配信メカニズム(例外をスローし、一定時間後にJMSメッセージを再配信させる)に依存することにしました。」

これは、Transaction1が論理的に終了した後に開始する2番目のトランザクションに、Transaction 1の変更がまだ表示されていないことを検出し、技術的な例外でそれ自体を爆破する方法がある場合にのみ、フェイルプルーフになります。

トランザクション1とは異なるプロセスであるトランザクション2がある場合、これを確認できる可能性があります。ほとんどの場合、トランザクション1の出力は、トランザクション2を成功させるために必要です。フライドポテトは、じゃがいもがあれば作れます…じゃがいもがない場合は、爆破して次回からやり直してください。

ただし、DBが古くなっているために壊れているプロセスが、トランザクション1自体で実行されているプロセスとまったく同じである場合。ジャガイモを腸に追加しているだけで(たとえば、dbテーブル)、腸が溢れていることを検出できず、トランザクションを実行し続けてポンプを上げます...このようなチェックは手に負えない可能性があります。

ある種の何かが、たまたま私の場合です。

これに対する理論的な解決策は、JPAの@Versionフィールドに相当する人工エンティティを作成し、共通のエンティティを更新するためにシリアルに実行する必要のある各プロセスを強制することにより、DBでダーティリードを誘導しようとすることです。トランザクション2と1の両方が共通エンティティの共通フィールドを更新する場合、プロセスを中断する必要があります。2番目のトランザクションでJPAオプティミスティックロック例外が発生するか、DBからダーティリード更新例外が発生します。

私はまだこのアプローチをテストしていませんが、悲しいことに、それは必要な回避策になるでしょう。

于 2016-06-29T13:45:03.810 に答える