java - Spring 中@Async 方法上的@Transactional

标签 java spring asynchronous transactions

我有一个场景,我调用了三个 @Transactional @Async 方法。一切正常,除了所有三种方法都有自己的事务上下文。我想在调用方法的事务上下文中执行它们。

我的调用方式是这样的:

 @Transactional
 public void execute(BillingRequestDto requestDto) {
        try {
            LOGGER.info("Start Processing Request : {}", requestDto.getId());
            List<Future<?>> futures = new ArrayList<>();
            futures.add(inboundProcessingService.execute(requestDto));
            futures.add(orderProcessingService.execute(requestDto));
            futures.add(waybillProcessingService.execute(requestDto));
            futures.stream().parallel().forEach(future -> {
                try {
                    future.get();
                } catch (Exception e) {
                    futures.forEach(future1 -> future1.cancel(true));
                    throw new FBMException(e);
                }
            });
            requestDto.setStatus(RequestStatus.SUCCESS.name());
            requestDto.setCompletedAt(new Date());   
            LOGGER.info("Done Processing Request : {}", requestDto.getId());

        } catch (Exception e) {
            requestDto.setStatus(RequestStatus.FAIL.name());
            requestDto.setCompletedAt(new Date());
            throw new FBMException(e);
        } 
    }

并且所有被调用的方法都用@Async@Transactional注释。

@Transactional
@Async
public Future<Void> execute(BillingRequestDto requestDto) {
    LOGGER.info("Start Waybill Processing {}", requestDto.getId());
    long count = waybillRepository.deleteByClientNameAndMonth(requestDto.getClientName(), requestDto.getMonth());
    LOGGER.info("Deleted  {} Records for Request {} ", count, requestDto.getId());
    try (InputStream inputStream = loadCsvAsInputStream(requestDto)) {
        startBilling(requestDto, inputStream);
    } catch (IOException e) {
        LOGGER.error("Error while processing");
        throw new FBMException(e);
    }
    LOGGER.info("Done Waybill Processing {}", requestDto.getId());
    return null;
}

这三种方法的实现大致相同。

现在,如果这些方法中的任何一个出现故障,则仅针对该方法回滚事务。

我的要求是在调用方法事务上下文中运行所有三个方法,这样一个方法中的任何异常都会回滚所有三个方法。

如果我禁用 @Async,这种情况会很有效。有时间采取方法,所以我希望它们并行运行。

请为此提出任何解决方案。

最佳答案

我猜你应该使用 spring TransactionTemplate用于程序化控制。
主线程应该执行控制,如果任何线程抛出异常你应该通知其他线程他们应该回滚。

比如说,每个“事务性”线程在执行后都应该wait(),如果没有异常就执行notifyAll(),然后在你的线程中执行事务提交,在如果出现异常,您应该调用 Thread.interrupt() 并执行回滚。

关于java - Spring 中@Async 方法上的@Transactional,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46270739/

相关文章:

java - 使用带有 CompletableFuture 的默认公共(public) fork/join 池进行长阻塞调用是不好的做法吗?

java - 将异步计算包装成同步(阻塞)计算

node.js - 从回调中设置全局变量

java.rmi.RemoteException : EJB Exception: ; nested exception is:

java - NotSerializedException 实现 Serialized 的序列化类

java - 同一个类上注解Entity和Component是不是错了

java - 使用 Spring Security 进行 hibernate

java - 尝试通过 SSL 连接到服务器的 SSLHandshakeException

java - android java求解字符串格式的方程

c# - Java 中的 Process.Start 帮助