[Seasar-user:12066] Re: Transaction境界を設定したコンポーネントが階層的に呼び出された場合

Koichi Kobayashi [E-MAIL ADDRESS DELETED]
2007年 12月 12日 (水) 20:30:03 JST


小林 (koichik) です.

Date:    Wed, 12 Dec 2007 19:24:25 +0900
From:    "Mitsutaka Sato" <[E-MAIL ADDRESS DELETED]>
To:      [E-MAIL ADDRESS DELETED]
Subject: [Seasar-user:12064] Re: Transaction境界を設定したコンポーネントが階層的に呼び出された場合

> あるトランザクションAの途中に requiresNewTx で別のトランザクションBを取得して
> 処理を行なうロジックがあるとき、AでsetRollbackOnly()をした後に、Bが実行されると
> 以下のExceptionが発生します。
略
> Aをsuspendしようとするときに発生するようですが、これは仕方の無いことでしょうか?

JTA の仕様的には suspend できてもいいかも
しれませんが,その必要があるのがおかしいと
いうか,トランザクションをロールバックすることを
決めているのに,その中で requiresNew な
トランザクションを実行する必要があるというのが
随分とイレギュラーに感じます.

>  public void execute() {
>    doSomething();
>    try {
>      fugaService.execute();
>    } catch (Exception e) {
>      userTransaction.setRollbackOnly();
>      log.info(e);
>    }
>    doSomething2();
>    otherTxService.execute();     <== S2Tx で requresNewTx をAspectしてるメソッド
>    doSomething3();
>  }

例外が起きた時点で後続の処理を続ける必要が
本当にあるのでしょうか?
あるいは,後続の処理を実行する必要があるのに,
トランザクションをロールバックする必要が
あるのでしょうか?
なんとなく,イヤなニオイを感じる話に
聞こえるのですが.

どうしても必要なら,

 public void execute() {
   boolean rollingBack = false;
   try {
     doSomething();
     try {
       fugaService.execute();
     } catch (Exception e) {
       rollingBack = true;
       log.info(e);
     }
     doSomething2();
     otherTxService.execute();     <== S2Tx で requresNewTx をAspectしてるメソッド
     doSomething3();
   } finally {
     if (rollingBack) {
       userTransaction.setRollbackOnly();
     }
   }
 }

という手もあると思います.


-- 
<component name="koichik">
    <property name="fullName">"Koichi Kobayashi"</property>
    <property name="email">"[E-MAIL ADDRESS DELETED]"</property>
    <property name="blog">"http://d.hatena.ne.jp/koichik"</property>
</component>



Seasar-user メーリングリストの案内