特定の場所だけトランザクション制御を外すには

実行するActionクラスのメソッドに以下のアノテーションを書く。
(ちなみにS2Chronsの場合は、TaskクラスのdoExecuteメソッド)


@TransactionAttribute(TransactionAttributeType.NEVER)



これでトランザクション制御から外れるので、
一昔前のように書いてあげれば良い。
userTransaction.begin();

〜 処理 〜

userTransaction.commit();


userTransactionは通常通りDIで取得できる。




デフォルトでは例外が起きた場合、
トランザクションロールバックが設定される。

通常はコレで困ることはないのだが、
例えば例外が起きたことによってDBの内容を変更したい場合には、全てロールバックされると困るので以下のように対応した。



1.@TransactionAttribute(TransactionAttributeType.NEVER)で基点となるメソッドからトランザクション制御を外す。

2.userTransaction.begin()でトランザクション1を開始

3.目的の処理

4.目的の処理中の例外をキャッチ

5.userTransaction.rollback()で目的の処理の例外によるエラーをロールバックしてトランザクション1を終了

6.userTransaction.begin()でトランザクション2を開始

7.4でキャッチした例外をもとにDBにINSERT

8.userTransaction.commit()でトランザクション1もしくは2を終了



例外さえ起きなければ4〜7は通らずbegin〜commitとなる。





気をつけるのは、
@TransactionAttributeを指定するメソッドは処理の開始となるメソッドでなければならない。


例外が発生する箇所だけをアノテーションで解除しようとしても、
[既に別のトランザクションが割り当てられています]との別の例外が発生してしまう。



参照サイト
http://d.hatena.ne.jp/izuno4t/20080811/1218419884
http://sastruts.seasar.org/featureReference.html#Transaction
http://s2container.seasar.org/2.4/ja/ejb3.html#TransactionAttributeAnnotation