【问题标题】:Transaction rollback when @Async method fails@Async 方法失败时事务回滚
【发布时间】:2019-02-14 05:46:28
【问题描述】:

我正在尝试阅读有关 Transaction 的信息,但我不明白如何回滚异步方法调用,是否有可能这样做。

我面临一个问题,例如,用户可以选择手动或无人驾驶汽车。因此,如果他选择无人驾驶,则手动配置将被禁用,反之亦然。考虑一下,他正在从无人驾驶转向手动,无人驾驶配置被关闭,我调用另一个服务来关闭手动配置(这发生在异步调用中)。我添加了@Async 是有原因的,因为它很耗时。

例子

// 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;
   }

}

如果rest调用禁用手​​动配置时出现调用错误,则无人驾驶配置打开但手动配置未关闭,两者都打开。

问题:

  1. @Transactional 添加到调用者和被调用者方法有效吗? - 可以,但是会影响性能,这种情况下@Async是没有用的。

  2. 调用方方法应该有@Transactional,但@Async 方法应该有@Transactional(REQUIRES_NEW)?在调用方方法@Transaction 上回滚是否会在被调用方方法中回滚检查异常的事务?

我期待一个解决方案,在不影响性能的情况下实现数据的完整性(我希望 @Async 以现在的方式工作)

【问题讨论】:

    标签: java spring asynchronous


    【解决方案1】:

    这是一个很好的问题,我前段时间遇到过。

    1. 不,添加 @Transactional 不起作用,因为当 @Async 方法启动时,它正在新线程上运行
    2. 我认为没有办法基于 @Async 方法调用进行回滚。
    3. 你可以在没有异步调用的情况下让回滚工作,我不知道为什么你需要将无人驾驶方法调用为@Async,但如果你删除它就可以了。

    【讨论】:

    • 谢谢。我需要它异步,因为它正在对其他服务进行休息调用。
    【解决方案2】:

    我不建议合并@Async@Transactional,所以我可以以任何一种方式运行服务。我只是在服务周围创建异步包装器,并在需要时使用这个包装器。

    @Transactional 与 @Async

    @Transactional Spring @Component 调用带有 @Async 注释的方法时,不会发生这种情况。对异步方法的调用由任务执行器安排并在稍后执行,因此作为“新”调用处理,即没有事务上下文。如果@Async 方法(或声明它的@Component)本身不是@Transactional,Spring 将不会管理任何需要的事务。

    如果使用 @Async 注释,则应特别注意事务。在这种情况下,事务通过调用层次结构从一个 Spring @Component 传播到另一个。

    为了让Spring管理@Async方法的事务,@Component或者方法本身应该声明@Transactional注解,这样Spring将管理事务,即使一个方法正在执行异步。

    【讨论】:

    • 如果我正确理解了您的答案,您是说将 Transaction 添加到 Async 方法会起作用吗?它仍然不起作用,因为我的调用函数没有事务(默认情况下传播是必需的)。如果我将 Transaction 添加到这两个方法中,那么 Async 将没有意义,因为它会在提交事务之前等待 Async 线程完成。你可以给我一个例子吗?你可以考虑我上面的那个。围绕服务创建异步包装器是什么意思?
    猜你喜欢
    • 1970-01-01
    • 2021-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-11
    相关资源
    最近更新 更多