S2JMS-Container 向けのメモ.
S2JMS-Container を使った受信メッセージ処理におけるトランザクション境界は,JMS メッセージをトランザクショナルに受信するかどうかの設定で異なります.
トランザクショナルにメッセージを受信する場合,トランザクション境界は S2JCA が設定します.
S2JMS-Container の MessageListener#onMessage(Message)
はトランザクション境界の中で呼び出されます.
ただし,S2JMS-Container 上のアプリケーションはこのトランザクション境界を前提にせず,DB アクセス等を行うなら適切なところに j2ee.txRequired
等のインターセプタを設定した方がいいと思います.
非トランザクショナルにメッセージを受信する場合,S2JCA はトランザクション制御を行いません.
S2JMS-Container も行いません.
S2JMS-Container 上のアプリケーションは,適切なところに j2ee.txRequired
等のインターセプタを設定する必要があります.
S2JMS-Container が呼び出したアプリケーションのリスナーメソッドが例外をスローした場合の S2JMS-Container の対処は,メッセージをトランザクショナルに受信したかどうかで異なります.
トランザクショナルに受信したかどうかは,すでにトランザクションが開始されているかどうかで判断することができます.
TransactionManager#getTransaction()
の戻り値が null
でなければトランザクションが開始されています.
トランザクショナルに受信したメッセージの処理でアプリケーションが例外をスローした場合は,TransactionManager#setRollbackOnly()
を呼び出して例外を破棄します.
非トランザクショナルに受信したメッセージの処理でアプリケーションが例外をスローした場合は...
どうしていいか分からない.(;_;)
メッセージの処理に失敗したことをリソースアダプタに伝えるには例外を投げるしかないはず.
でもでも,先にも書いたように少なくとも ActiveMQ は 10 回程度例外を投げるとそのコネクションではもうメッセージを受信できなくなってしまうわけで...
といって例外を投げなければ,リソースアダプタの設定次第では Ack が返されたり...
この辺は ActiveMQ 固有の設定の問題なのかなぁ.
このケースは継続して調査ということで.