S2 の JTA について

S2 は Extension として JTA の実装を提供しています.
この JTA 実装では,トランザクションがコミットされる時だけでなく,ロールバックされる時も Synchronization#beforeCompletion() を呼び出し (コールバック) しています.が,ロールバック時には Synchronization#beforeCompletion() はコールバックされないのが正しいのではないかという気がします.


JTA の仕様でも CORBA OTS の仕様でもこの辺りが明記されていない気がするのですが,ほぼ同等と思われる EJB2.1 の「7.6 Stateful Session Bean State Diagram」ではトランザクションがコミットされる場合にのみ SessionSynchronization#beforeCompletion() が呼び出されることが明示されています.JDO の仕様も同様です.
他の JTA 実装としては,JOTM はロールバック時に Synchronization#beforeCompletion() を呼び出していません.コードは見てないけどぐぐったら JBoss でも同様っぽい感じ?
Spring FrameworkJTA の実装を提供しませんが,独自の PlatformTransactionManagerJTASynchronization によく似た TransactionSynchronization を定義しています.こいつの場合はロールバック時にも beforeCompletion() が呼び出されることが明示されています.かわりに (?) beforeCommit() というメソッドも定義されていて,こいつはコミットする場合にのみ呼び出されます.まぁ,あんまり参考にならない感じ.


解釈としては,トランザクションがコミットまたはロールバックされた後に呼び出される Synchronization#afterCompletion(int status) にはトランザクションのステータスが引数で渡されるのに対して,Synchronization#beforeCompletion() にはステータスが渡されません.つまり必要ないという事で,その理由はトランザクションがコミットされる場合にしか呼び出されないからステータスに応じた処理をする必要がないという事ではないかなぁと思います.


そんなわけで (どんなわけで?),
S2 の JTA 実装でもロールバック時には Synchronization#beforeCompletion を呼び出さない
というように変更したいと考えています.
Synchronization を使うことはそれほど多くないと考えていますが,もし Synchronization をお使いになっている方で,この変更が望ましくないという場合にはコメントください.
あるいは,JTA 仕様の解釈に関するご意見,WebSpheare や WebLogic 等における JTA 実装の挙動に関してご存じの方もコメント頂けると幸いです.
よろしくお願いします.


22:44 追記
Apache Geronimoロールバックの時にも Synchronization#beforeCompletion() を呼び出してるなぁ...


23:23 追記
Transaction#setRollbackOnly() を呼び出した後に Transaction#registerSynchronization(Synchronization) しようとすると RollbackException が飛んでくることになっています.つまり,ロールバックされるトランザクションSynchronization を登録してもしょうがないということで,これもロールバックされるトランザクションでは Synchronization#beforeCompletion() を呼び出すべきでないことを暗に示しているような気のせいが.


00:00 追記
CORBA OTS 1.4 (03-09-02) の「2.9 Synchronization Interface」に次の記述が.

If the transaction is instructed to roll back rather than be committed, the object will only be notified after rollback completes.

これで (だいたい) 安心.
少なくとも CORBA OTS (つまり JTS) では Synchronization#before_completion() が呼び出されるのはトランザクションがコミットされる場合だけで,ロールバックされる際には呼び出されないという事ですね.
そして JTAJTS の上位に構築できることを意図していて,JTASynchronizationJTSSynchronization とメソッドの命名規則に基づく違いがあるだけという事から,JTASynchronization#beforeCompletion()ロールバック時には呼び出されないのが妥当といえるのではないかと.


00:30 追記
Oracle9iAS はロールバック時にも Synchronization#beforeCompletion() を呼び出しているらしい.
しかし (9iAS にバンドルされている) TopLink はそれを想定していなくて例外が吹っ飛んだりしていたらしい.でもどうせロールバックするんだから例外が吹っ飛んでもどうという事はなかったと思われますが.
9iAS の 9.0.3.3 くらいまでの話.その後なんらかの対応がなされたらしいけれど,どういう対応 (9iAS が Synchronization#beforeCompletion() を呼び出さないようにしたのか TopLink で善処したのか) をしたのかは不明.