2016-09-05 2 views
5

トランザクションメソッドを@Asyncと記述すると、@Transactionalの例外をキャッチすることはできません。 ObjectOptimisticLockingFailureExceptionのように、トランザクションコミットなどの間にメソッド自体の外部にスローされるためです。@Asyncでトランザクション例外をキャッチする方法は?

例:

public class UpdateService { 
    @Autowired 
    private CrudRepository<MyEntity> dao; 

    //throws eg ObjectOptimisticLockingFailureException.class, cannot be caught 
    @Async 
    @Transactional 
    public void updateEntity { 
     MyEntity entity = dao.findOne(..); 
     entity.setField(..); 
    } 
} 

私は次のように私は一般に@Async例外をキャッチすることができます知っている:

@Component 
public class MyHandler extends AsyncConfigurerSupport { 
    @Override 
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { 
     return (ex, method, params) -> { 
      //handle 
     }; 
    } 
} 

をしかし、私は場合にのみ、別の方法で指定された例外を処理することを好むだろうそれは​​内で発生します。

質問:どうすればを受け取ることができます​​?

唯一の機会ですか:@Serviceを追加して​​をラップし、try-catchブロックを持っていますか?それとももっとうまくできますか?

答えて

1

Spring 4.3で動作するself-injectingお豆を試すことができます。自己注射は一般的には良い考えではありませんが、これは正当なユースケースの1つです。

@Autowired 
private UpdateService self; 

@Transactional 
public void updateEntity() { 
    MyEntity entity = dao.findOne(..); 
    entity.setField(..); 
} 

@Async 
public void updateEntityAsync(){ 
    try { 
     self.updateEntity(); 
    } catch (Exception e) { 
     // handle exception 
    } 
} 
+0

実際に自己注入のための有効な使用法であれば十分です。問題は、それは? – membersound

+0

@ mememound:私の意見では、それは有効です。それを悪用して、1000行の "神のクラス"になるようにすることも可能です。しかし、あなたの例外処理はこのクラスに特有なので、なぜクラスに入れないのですか?もし誰かがそれを悪い習慣と考えるなら、彼らはここにコメントを残すことができます... – user140547

+0

それはうまくいかず、「1豆の間に循環依存があります。 spring-boot.1.4.0 with spring.4.2.3 – membersound

関連する問題