Reputation: 86747
When writing transactional methods with @Async
, it's not possible to catch the @Transactional
exceptions. Like ObjectOptimisticLockingFailureException
, because they are thrown outside of the method itself during eg transaction commit.
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 I can catch @Async
exceptions in general as follows:
@Component
public class MyHandler extends AsyncConfigurerSupport {
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return (ex, method, params) -> {
//handle
};
}
}
But I'd prefer to handle the given exception in a different way ONLY if it occurs within the UpdateService
.
Question: how can I catch it inside the UpdateService
?
Is the only chance: creating an additional @Service
that wraps the UpdateService
and has a try-catch
block? Or could I do better?
Upvotes: 7
Views: 1667
Reputation: 8200
You could try self-injecting your bean which should work with Spring 4.3. While self-injecting is generally not a good idea, this may be one of the use-cases which are legitimate.
@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
}
}
Upvotes: 2