2011-11-09 21 views
7

私は同じクラスの別の@Transactionalメソッドを呼び出す@Transactionalメソッドを持つ@Serviceクラスを持っています。私はこれについてロールバックの動作をテストしていましたが、正しく動作していないことがわかりました。 「 - ロールバックJDBCTransactionを」ログが表示さにもかかわらず、私は、データベースをチェックし、変更があるmethodOneを実行した後@入れ子になったメソッドとロールバック

@Service 
public class DefaulService implements ervice 
{ 
    @Transactional 
    public void methodOne() 
    { 
     methodTwo(); 

      //question edited 
      //this seems to be the problem 
      this.serviceDAO.executeUpdateOperation(); 

     //test rollback 
     throw new RuntimeException(); 
    } 

    @Transactional 
    public void methodTwo() 
    { 
     //DAO stuff 
    } 
} 

:コードは次のようになります。

個別にmethodTwoを呼び出し、最後に例外を追加すると、変更が正しくロールバックされます。

入れ子の@Transactional呼び出しで発生した変更をmethodOneが適切にロールバックできるようにする方法はありますか?私はREQUIREDのデフォルト伝播がこれを達成するという印象を受けていましたが、うまく動作していないようです。おかげ

UPDATE

[OK]を、私はちょうど何かを気づきました。例外スローの直前に、私はサービスのDAOを呼び出し、 'executeUpdate'を介して手動アップデートを実行しています。この行をコメントすると、ネストされたロールバックが機能します。したがって、問題は実際にDAOを呼び出してexecuteUpdateクエリを実行しているようです。しかし、これも現在のトランザクションの中で実行すべきではありませんか?

+0

'methodOne()'から 'methodTwo()'を呼び出すとき、 '@ Transactional'アノテーションが無視されることは承知していますか?詳細については、私の[記事](http://nurkiewicz.blogspot.com/2011/10/spring-pitfalls-proxying.html)を参照してください。しかし、これはあなたの問題を引き起こすことではありませんが、知る価値があります。 –

+0

はい、しかし、MethodTwoは独立して呼び出すことができるので、そのような場合には独自の注釈が必要です。今、私はexecuteUpdateによってトランザクションがコミットされる理由は分かりませんが、おそらくそれがデフォルトの動作です。 – JayPea

+1

serviceDaoのトランザクション伝播とは何ですか?いつかREQUIRES_NEWですか? – Hendrik

答えて

1

メソッドを呼び出すときにbean factoryから "ervice"のインスタンスを取得しているのは間違いありません。 Beanファクトリは、各メソッド呼び出しの周りにトランザクションロジックを実装するプロキシを設定する必要があります。私は、これは "外部者"がプロキシを介してメソッドを呼び出すときにのみ機能し、あるメソッドが別のメソッドを呼び出すときには必ずしも機能しないという印象を受けました。そのメソッドは実装オブジェクト内の直接呼び出しであり、AOPプロキシを経由しません。

+0

これは、使用しているAOPアプローチの種類によって異なります。 Tomasz Nurkiewiczの[link](http://nurkiewicz.blogspot.com/2011/10/spring-pitfalls-proxying.html)をチェックしてください。 JayPeaが説明している動作も説明できません。 –

関連する問題