2

JTA、2 フェーズ コミット、JMS および JDBC トランザクションに苦労しています。アイデアは(要するに)

  1. キューでメッセージを受信する
  2. いくつかのデータベース操作を実行します
  3. データベース操作が成功したときに、メッセージを確認します

を取得しXAQueueConnectionFactory、 を作成しXAQueueSession、セッションからレシーバーを作成し、メッセージ リスナーを設定しました。

リスナー内のonMessageメソッドで、ユーザー トランザクションを開始し、jdbc を実行してトランザクションをコミットするか、何か問題が発生した場合はロールバックを実行します。ここで、ユーザー トランザクションがコミットされたときに、メッセージが確認されることを期待 (別名「希望」) しました。

しかし、そうはなりません。メッセージはまだキューにあり、何度も再配信されます。

私は何が欠けていますか?セッションを再確認したところ、承認モードは実際には " SESSION_TRANSACTED" であり、getTransactedtrue を返します。

Java EE コンテナーも、スプリングも、メッセージ駆動型 Bean もありません。私はスタンドアロンの JTA bitronix を使用しています。

4

3 に答える 3

2

これには XA は必要ありません。アルゴリズムに従ってください: メッセージを受信し、DB 操作を実行し、メッセージを確認します...文字通り、それが解決策です。(トランザクション セッションの代わりに、おそらく明示的な CLIENT_ACKNOWLEDGE を選択するだけです。) DB 操作の実行中にアプリケーションが失敗した場合は、JMS メッセージを確認しないでください。再配信されます。アプリが DB txn の後、ack の前に失敗した場合、メッセージは再配信されますが、これを検出でき (再配信フラグはメッセージで true に設定されます)、メッセージを再処理するかどうかを決定できます。データベースの状態に基づいています。

于 2013-08-31T07:55:20.767 に答える
0

リスナー内でユーザートランザクションを開始すると言うとき、これはBeanマネージドトランザクション(BMT)を使用していることを示唆しているようです。そうする正当な理由はありますか?

Container Managed Transaction(CMT)を使用した場合、必要なものは無料で提供されます。

私が覚えている限り、UserTransactionは参加せず、メッセージ用に作成されたトランザクションに参加できないため、BMTでは不可能です。ただし、JavaEE仕様を再確認することをお勧めします。

編集:申し訳ありませんが、JavaEEコンテナを使用していないことに気づきました。

リスナー内で開始するユーザートランザクションが、メッセージに対して開始されたトランザクションの一部であることを確認しますか?db作業のために独立したトランザクションを開始しているようです。

コンテナを使用しない場合、JMS実装、つまりXAQueueConnectionFactoryなどを提供するのは誰ですか?

于 2013-03-04T10:51:10.587 に答える