@Transactional on Spring中的@Async方法

时间:2017-09-18 02:22:27

标签: java spring asynchronous transactions

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

我的通话方法是这样的:

@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; } ,此方案效果很好。有时间采取方法,所以我希望它们并行运行。

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

2 个答案:

答案 0 :(得分:1)

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

比如说,执行后的每个“事务”线程都应该wait(),如果没有异常只执行notifyAll()并且在你的线程中执行事务提交,如果异常,你应该调用{{1}并且做回滚。

答案 1 :(得分:0)

我认为您的scale方法会引发检查异常

@Async

,呼叫者可以使用以下注释:

@Transactional<br>
@Async<br>
public Future<Void> execute(BillingRequestDto requestDto) throw RollBackParentTransactionException {
...
}

应该起作用。