Transaction rollback when @Async method fails

问题: I am trying to read about Transaction but I cannot understand how would I rollback a async method call, is it even possible to do so. I am facing an issue where User can...

问题:

I am trying to read about Transaction but I cannot understand how would I rollback a async method call, is it even possible to do so.

I am facing an issue where User can select either select manual or driverless car for example. So if he selects driverless, then manual config will be disabled and other way round. Consider, he is moving from driverless to manual, driverless config is switched off and I make call to another service to switch off the manual configuration (which takes place in an Async call). I have added @Async for a reason as it is time consuming call.

example

// Caller
@Override
public void enableDriverlessDriving(DriverlessDriving driverlessConfig) {

     validator.validate(driverlessConfig);

     driverlessDao.update(driverlessConfig);

     if(drivelessConfig.isEnabled()) {

           manualService.onDrivelessEnabled(driverlessConfig.getUserId());
     }
}

// Callee
@Override
@Aysnc
public void onDrivelessEnabled(int userId) {

 .....
   // retrofit rest call. Timeout for 30 secs
   ManualConfig config = client.getManualConfiguration(userid,30);

   config.isEnabled(false);

   try {
         // retrofit rest call. timeout for 30 secs
         client.updateManualConfig(config, userId,30);
   }catch(CheckedExceptions e) { // throwing checked exceptions here.
      LOGGER.error(...)
      return;
   }

}

If there is an invoke error for rest call to disable manual config, the driverless config is switched on but manual config is not switched off, both are turned on.

Question:

  1. Adding @Transactional to the caller and callee method work? - May be, but then it will affect the performance, there would be no use of @Async in this case.

  2. Should caller method have @Transactional, but the @Async method should have @Transactional(REQUIRES_NEW)? Would having rollback on the caller method @Transaction rollback the transaction for checked exception in callee method?

I am expecting a solution where I achieve the integrity of data without compromising on performance (I want @Async to work in a way it works now)


回答1:

I will not suggest to merge @Async and @Transactional so i can run the service in either way. I just create async wrapper around the service and use this one instead if needed.

@Transactional with @Async

when a @Transactional Spring @Component calls a method annotated with @Async this does not happen. The call to the asynchronous method is being scheduled and executed at a later time by a task executor and is thus handled as a 'fresh' call, i.e. without a transactional context. If the @Async method (or the @Component in which it is declared) is not @Transactional by itself Spring will not manage any needed transactions.

If the @Async annotation is being used extra care should be taken with respect to transactions.In this case the transaction gets propagated through the call hierarchy from one Spring @Component to the other.

In order to make Spring manage the transaction of the @Async method either the @Component or the method itself should declare the @Transactional annotation, this way Spring will manage the transaction even if a method is being executed asynchronous.


回答2:

That's a great question, i came across at this some time ago.

  1. No, adding @Transactional is not going to work because when the @Async method starts it is running on a new thread
  2. I think there's no way to do a rollback based on a @Async method call.
  3. You can get rollback to work without async calls, I don't know why you need to call the driverless method as @Async, but if you remove it will work.
  • 发表于 2019-02-15 16:00
  • 阅读 ( 797 )
  • 分类:sof

条评论

请先 登录 后评论
不写代码的码农
小编

篇文章

作家榜 »

  1. 小编 文章
返回顶部
部分文章转自于网络,若有侵权请联系我们删除