2015-10-22 23 views
7

REQUIREDの場合、呼び出し側メソッド自体がtransactionnalの場合、現在のメソッドは、囲みトランザクションプロパティ(rollbackForなど)が異なる場合、それらをオーバーライドしますか?Spring @Transactional Annotationプロパティの優先順位/継承

イラスト:

Class A { 
    @Transactional(propagation = Propagation.REQUIRED, 
     rollbackFor = { SomeException.class}) 
    void foo() { 
     try { 
      b.bar(); 
     } catch (OtherException e) { 
      // is the transaction marked as rollback-only at this point ? 
     } 
    } 
} 

Class B { 
    @Transactional(propagation = Propagation.REQUIRED, 
     rollbackFor = { OtherException.class}) 
    void bar() { 
     [...] 
    } 
} 

編集

さて、私はスコープの回答のうち些細避けるしたいと思いますので、春の繁殖取り扱いのI'amは認識して、のは明確にしましょう。

PROPAGATION_REQUIRED

が伝播設定がPROPAGATION_REQUIREDのとき:あなたがいない場合は、下記の文書の関連部分が

ですが、私はちょうど私の上記の例について最初の部分を明確にしたいと思います論理 トランザクションスコープは、設定が である各メソッドに対して作成されます。このような各論理トランザクションスコープは、外部トランザクションスコープ が内部トランザクションスコープから論理的に独立している状態で、個別にロールバックのみのステータスを決定することができます。 コースのうち、標準のPROPAGATION_REQUIRED動作の場合、これらすべてのスコープは同じ物理トランザクションにマップされます。内部トランザクションスコープに ロールバック専用マーカーが設定されていると、 のように、実際にコミットする外部トランザクションのチャンスは になります。

しかし、内側トランザクションスコープは ロールバックのみのマーカーを設定する場合には、外側のトランザクションがロールバック 自体を決定していない、など(サイレントインナー トランザクションスコープによってトリガ)ロールバックが予想外であります。対応する その時点でUnexpectedRollbackExceptionがスローされます。これは、トランザクションの呼び出し元が に誤解されることがないように、実際にはコミットが実行されなかったと想定して、 の動作が予想されます。したがって、 内部トランザクション(外側の呼び出し元が認識しないトランザクション)がサイレントに にトランザクションをロールバック専用としてマークすると、外側の呼び出し元は依然として を呼び出します。外側の呼び出し側は UnexpectedRollbackExceptionを受け取る必要があります。これは、ロールバックが だったことを明確に示すためです。

私の質問はこれと言い換えることができます。

は、論理トランザクションのスコープは、トランザクションのプロパティを保持していますか?

+0

あなたはhttp://stackoverflow.com/questions/を参照することができます8490852/spring-transactional-isolation-propagation/32223597#32223597複数のシナリオで異なる伝播を行う場合 –

答えて

1

私はテストケースを設定しましたが、答えは「はい」です。

トランザクション論理スコープはトランザクションプロパティを保持し、その境界は実際には注釈付きメソッドです。

したがって、基礎となる物理トランザクションが両方のメソッドで同じであっても、論理プロパティは各メソッドに適切であり、内部メソッドは外部メソッドトランザクションのロールバックを強制できます。 最後にコミットをトリガーすると、UnexpectedRollbackExceptionが発生します。

cf.春TransactionInterceptor(コメントは私のものです)

try { 
     retVal = invocation.proceed(); 
} 
catch (Throwable ex) { 
     completeTransactionAfterThrowing(txInfo, ex); 
     throw ex; 
} 

completeTransactionAfterThrowing():

// txinfo is proper to the invocation target method 
if (txInfo.transactionAttribute.rollbackOn(ex)) { 
      try { 
       txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus()); 
      } 

AbstractPlatformTransactionManager.processRollback():

else if (status.isNewTransaction()) { //requiresnew 
    doRollback(status); 
} 
else if (status.hasTransaction()) { //requiered 
     [...] 
     doSetRollbackOnly(status); 
    } 
} 
+0

NOTA:デバッガを使用して内部変数の状態を信頼しない場合、明示的にgetterを呼び出しますTransactionAspectSupport.currentTransactionStatus()。isRollbackOnly() – Gab

0

spring documentationの16.5.7項を参照してください。 内部メソッドは、トランザクションコンテキスト内で呼び出されたときにREQUIREDでアノテーションを付けても、同じ物理トランザクションにマップされます。仕様の私の理解で

+1

申し訳ありませんが、あなたは質問。 – Gab

0

、私は、この例で言う:

Class A { 
    @Transactional(propagation = Propagation.REQUIRED, 
     rollbackFor = { SomeException.class}) 
    void foo() { 
     try { 
      b.bar(); 
     } catch (OtherException e) { 
      // the transaction is marked as rollback-only by the inner call as it thrown an OtherException 
      // XXX --- or not if inner logical scope does not handle overridden property 'rollbackFor' ? --- 
      // anyway, we avoid UnexpectedRollbackException by enforcing physical rollback to outter scope programmatically, by throwing : 
      throw new SomeExeption(e); 
     } 
    } 
} 

Class B { 
    @Transactional(propagation = Propagation.REQUIRED, 
     rollbackFor = { OtherException.class}) 
    void bar() { 
     [...] 
    } 
} 

だから私たちのように質問を再定式ことができます。「rollbackFor」プロパティは、内部論理トランザクション・スコープ・マネジメントによって処理され上書きしますか?

ちなみに、使っているトランザクションマネージャのクラスとバージョンはなんですか?

関連する問題