How to catch transactional exceptions in @Async?

When writing transactional methods with @Async it is not possible to throw @Transactional exceptions. Like ObjectOptimisticLockingFailureException , because they are thrown outside the method itself, for example, when a transaction is committed.

Example:

 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(..); } } 

I know that I can catch @Async exceptions as a whole as follows:

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

But I would prefer to handle this exception in a different way ONLY if it occurs in the UpdateService .

Question: how can I catch it inside UpdateService ?

The only chance: create an extra @Service that wraps the UpdateService and has a try-catch ? Or am I better?

+5
source share
1 answer

You can try to preserve your bean, which should work with Spring 4.3 . Although self-injection is generally not a good idea, this may be one of the precedents that are legal.

 @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 } } 
+1
source

All Articles