简体   繁体   中英

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 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)

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.

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, ie 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.

Try below approach,

  1. Create a separate class. Declare that as a bean under spring configuration.
  2. Add all async methods in this class.
  3. Autowire this class under the service class.
  4. Inside a Transactional method from service class, call async method from the class created in 1st step.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM