S2JMS 開発記 続 MessageEndpoint

コミットしますた.
S2JCA-ActiveMQactivemq/bin/activemq.bat を実行しておいて,org.seasar.jca.mi.jms.ActiveMQTest で動作確認ができます.
量が多いので分かりにくいですが,コンソール出力を見ると複数のスレッドで受信メッセージをバッサバッサと捌いている様子が窺えるはず.


ちょっと気になったことがあって,ActiveMQ は受信メッセージの処理が一定回数以上失敗に終わる (MessageLister#onMessage(Message) から例外がスローされる) と,そのコネクションからのメッセージ配信を中断してしまうようです.
これは特定のメッセージを何回失敗したらということではなく,コネクション単位で数えているっぽい.
自分の環境だと,連続じゃなくても通算 11 回 (たしか) 失敗するとそれ以降メッセージが来なくなります.
そうなると,その MessageEndpoint にはもはやメッセージが届かないため,受信アプリケーションとしては全くの役立たずになってしまうということに.
そんなわけで (どんなわけで?),その状況になったら MessageEndpoint を非アクティブ化して,新しい MessageEndpoint をアクティブ化すべきのような気のせいがしますが,その状況になっていることを知る手段ってある?
JCA 仕様には見当たらないような...


例外を伝えず単にロールバックするだけだと,そのメッセージは 5 回ばかり再配信される (通算 6 回 MessageListener#onMessage(Message) が呼び出される) っぽい.
この場合は何回ロールバックしてもコネクションは配信を続けてくれる模様.500 回くらいしか試してないけど.
そんなわけで (どんなわけで?),ActiveMQ に例外が伝わらないようにすればいいのかとも思ったのですが,JCA 仕様ではアプリケーションで発生した例外はリソースアダプタに渡せと書いてあるような.


ってことは,S2JMS-Container (JCA 仕様的にはアプリの一部) で例外をハンドリングすればいいのかも.
トランザクショナルなメッセージに限ると,本当のアプリケーションから例外が飛んできたら,S2JMS-Container は TransactionManager#setRollbackOnly() を呼び出して例外を捨ててしまえばいい,みたいな (もちろんロギングくらいはする).
そうすると ActiveMQ のデフォルトでは 5 回までリトライできるよ,と.
OracleAQ なんかもロールバックされたメッセージをリトライする上限を設定できるので,こういう場合は S2JMS-Container でリトライの制御をする必要はないわけですが,そうじゃない JMS 実装のことも一応考えておくテスト.