22

アプリケーション サーバー (Glassfish) でデータベースJMSを使用する非常に単純なシナリオがあります。シナリオは非常に単純です。

1. an EJB inserts a row in the database and sends a message.
2. when the message is delivered with an MDB, the row is read and updated. 

問題は、挿入がデータベースにコミットされる前にメッセージが配信されることがあるということです。これは、2 フェーズ コミット プロトコルを考えると理解できます。

1. prepare JMS
2. prepare database
3. commit JMS
4. ( tiny little gap where message can be delivered before insert has been committed)
5. commit database

この問題についての人と話し合ったことがありますが、答えはいつも「奇妙です。すぐに使えるはずです」でした。

私の質問は次のとおりです。

  • そのままでどのように機能するのでしょうか?
  • 私のシナリオは非常に単純に聞こえますが、同様の問題を抱えている人がもっといないのはなぜですか?
  • 私は何か間違ったことをしていますか?この問題を正しく解決する方法はありますか?

問題の私の理解についてもう少し詳しく説明します。

このタイミングの問題は、参加者がこの順序で処理される場合にのみ存在します。2PC が参加者を逆の順序 (最初にデータベース、次にメッセージ ブローカー) で処理する場合は問題ありません。問題はランダムに発生していましたが、完全に再現可能でした。

Glassfish のドキュメントにも、JTA、JCA、および JPA 仕様の分散トランザクションの参加者の順序を制御する方法が見つかりませんでした。使われる順番に応じて分散トランザクションに登録されると想定できますが、JPA などの ORM では、いつデータがフラッシュされ、いつデータベース接続が実際に使用されるのかを知ることは困難です。何か案が?

4

1 に答える 1

12

古典的な XA 2-PC 競合状態が発生しています。本番環境で発生します。

3つのことが思い浮かびます。

  1. JDBC が非 XA リソースである最後のエージェントの最適化 (回復セマンティクスの喪失)
  2. JMS Time-To-Deliver があります。(意図的にリアルタイムを失う)
  3. 再試行を JDBC コードに組み込みます。(機能への影響は最小限)

Weblogic には、この LLR 最適化があり、この問題を回避し、すべての XA 保証を提供します。

于 2010-03-29T11:32:55.947 に答える