アプリケーション サーバー (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 では、いつデータがフラッシュされ、いつデータベース接続が実際に使用されるのかを知ることは困難です。何か案が?