16

良い一日。次のコード:

 class A{
     private B b;
    @Transactional
    public SomeResult doSomething(){
        SomeResult res = null;
        try {
          // do something 
        } catch (Exception e) {
            res  = b.saveResult();
        }
        return res ;
    }
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
class B{
  public SomeResult saveResult(){
      // save in db 
  }
}

私が理解しているように、メソッドに例外がある場合doSomething、トランザクションはロールバックされません。そして、それを転がす方法は?そして SomeResult を返しました

4

2 に答える 2

22

プログラムで Rollback を呼び出さないでください。docsで推奨されている最善の方法は、宣言型アプローチを使用することです。そのためには、ロールバックをトリガーする例外に注釈を付ける必要があります。

あなたの場合、このようなもの

@Transactional(rollbackFor={MyException.class, AnotherException.class})
public SomeResult doSomething(){
   ...
}

@Transaction APIとトランザクションのロールバックに関するドキュメントをご覧ください。

ドキュメントの推奨事項にもかかわらず、プログラムによるロールバックを行いたい場合はTransactionAspectSupport、既に提案されているように呼び出す必要があります。これはドキュメントからのものです:

public void resolvePosition() {
  try {
    // some business logic...
  } catch (NoProductInStockException ex) {
    // trigger rollback programmatically
    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
  }
}

ただし、アーキテクチャの間違いがある可能性があります。メソッドが失敗し、例外をスローする必要がある場合、メソッドが何も返さないことを期待するべきではありません。おそらく、このメソッドに責任を与えすぎているので、データのみをモデル化する別のメソッドを作成し、何か問題が発生した場合は例外をスローして、トランザクションをロールバックする必要があります。とにかく、ドキュメントを読んでください。

于 2012-08-30T10:53:59.407 に答える
2

TransactionAspectSupport.currentTransactionStatus() ect トランザクション マネージャーを使用して TransactionStatus を取得し、Bean にトランザクション マネージャーで Rollback(DefaultTransactionStatus status) を呼び出してみます。

春のドキュメントを参照してください

可能であれば、ロールバックに宣言型アプローチを使用することを強くお勧めします。絶対に必要な場合は、プログラムによるロールバックを利用できますが、その使用法は、クリーンな POJO ベースのアーキテクチャを実現することとは対照的です。

于 2012-08-30T10:39:50.190 に答える