2017-06-19 12 views
1

REQUIRES_NEWが戻ってすべてのトランザクションをロールされた外側のトランザクションのロールバック:のGrails /春REQUIRES_NEWが

私はこの方法はまた、方法は@Transactional(propagation = REQUIRED)をマークしたBean内で@Transactional(propagation = REQUIRES_NEW) をマークしています。これらのメソッドは決して互いに呼び出しません。それらは別のBeanから個別に呼び出されます。しかし、私のメソッドがREQUIRES_NEWとマークされていない場合、REQUIREDとマークされたメソッド(問題がある)を含むトランザクション全体をロールバックします。

私の理解では、Spring AOPがこのように因数分解された場合、REQUIRES_NEWメソッドをインターセプトして新しい論理トランザクションを開始する可能性があります。

一般的な考え方は次のようになります。

@Transactional 
class TransactionalBean{ 

    @Transactional(propagation = REQUIRED) 
    public void methodA(){ //do transactional work } 

    @Transactional(propagation = REQUIRES_NEW) 
    public void methodB(){ //do transactional work } 
} 

そして呼び出しBeanはそうのようになります。

@Transactional 
class CallingBean{ 
    @Autowired 
    TransactionalBean 

    public void doWork(){ 
     TransactionalBean.methodA(); 
     TransactionalBean.methodB(); 
    } 
} 

だから、方法AとBが成功した場合、すべてが正常です。しかし、方法Bが失敗すると、方法Aで行われた作業はロールバックされます。私が理解しているのは、methodB()が呼び出されたときにAOPによって傍受され、新しいトランザクションを開始し、他のトランザクションを一時停止するが、動作していないということです。これをどうやって解決するのですか?私はGrails 2.5、Hibernate、JPAを使用しています。

+0

を使用するための注釈。 2.5はもはや維持されていない。 –

+0

残念ながら私はこのプロジェクトで2.5に固執しています。それはフレームワークの問題ですか? – dirtbiker

答えて

0

問題は、CallingBean@Transactionalとマークされた方法にあります。何が起こっているのは、CallingBeanがトランザクションを作成しているということです。つまり、t1としましょう。 CallingBeanは、メソッドAとメソッドBの2つのトランザクションメソッドを呼び出しています。 methodAはトランザクションを必要とするため、既存のトランザクションt1を使用します。しかし、メソッドBは注釈が新しいものを必要とするので、新しいトランザクションを作成します。t2としましょう。メソッドAのトランザクション境界は、コントロールがメソッドAを終了するときに終了しませんが、トランザクションが呼び出し元のBeanで開始されてからメソッドBが完了するまで有効です。トランザクションt2がメソッドBで失敗したので、例外は呼び出し元のBeanにバブルアップし、トランザクションt1は失敗します。

これを解決するには、必要に応じて次のいずれかを実行します。

CallingBeanクラスの@Transactional注釈をオフにします。

//@Transactional 
class CallingBean{ 
... 
} 

更新、それを修正するための最良の方法は、アップグレードすることですnoRollbackForオプション

@Transactional(noRollbackFor={WhateverException.class}) 
class CallingBean{ 
... 
} 
関連する問題