宣言的トランザクション〜わかりにくいと感じた原因

今後のために、SAStruts(やS2Struts)でのトランザクションについて調べたのですが、トランザクション境界やRequiresNew等の意味について、S2Txの資料を見ても結構はまってしまいました。

コレに関するよい資料が少なくて、焦りました。SAStrutsの機能リファレンス等を見ると、JTAを使うとあるのですが、JTAとか、X/Open XAのSpecificationを見ても、正解にはたどり着けなかったです。結局、だいぶ古い本だけど、手元の EJB・Servlet・JSP わかりやすいJ2EEのしくみ という本にヒントがありました。また、最近の本で、Javaデータアクセス実践講座 (DB Magazine SELECTION)も持っていて、これをちゃんと読んだらわかりました。

それで、どこにはまっていたかというと、たとえばSAStrutsチュートリアルでは、アクションとサービスの両方にRequiredのトランザクション属性が付くようになっていますが、このときアクションがサービスを呼び出す構造であれば、コミットはどこで行われるのかということ。
結論的には、アクションのメソッドを抜けたときにコミットが行われるはず。というのも、EJB3.0Final Release仕様の13.6.2 Container-Managed Transaction Demarcation for Session and Entity Beansのあたりでこの辺はたとえば次のように定義されているから。


13.6.2.2 REQUIRED
[...]
If the client invokes the enterprise bean’s method while the client is not associated with a transaction
context, the container automatically starts a new transaction [...]
The container attempts to commit the transaction when the business method has completed. [...]
(斜体強調オレ)

それで、何が問題かというと、よくあるEJBの説明などでは、前半の「トランザクションコンテキストに結び付けられてなければ、自動的にトランザクションを開始する」類の説明はなされているのですが、後半の「[トランザクションを開始した当の]ビジネスメソッド(要はさっきの例でいうとアクションのメソッド)が完了したときにトランザクションをコミットしようとする」の部分の説明が抜けているものがすごく多かったのです。

今後似たようなことを調べる人は、上記の参考書とか、評判のいいEJBの本などをまず参考にして、それからSeasarでの作りを見るなどしたほうが理解しやすいと思います。