나는 세 개의 @Transactional @Async
메쏘드를 호출하는 시나리오를 가지고있다. 모든 세 가지 방법은 자신의 트랜잭션 컨텍스트를 제외하고 잘 작동합니다. 메서드의 트랜잭션 컨텍스트를 호출하여이를 실행하려고합니다.@Async 메소드에서 @ Transactional @
내 소명 방법은 다음과 같이이다 :
@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
을 사용하지 않으면 잘 작동합니다. 내가 평행하게 달릴 수 있도록 시간을 보내는 방법이 있습니다.
해결 방법을 제안하십시오.
'@ Async' 메소드는 별도의 스레드에서 실행되므로 호출자의 동일한 트랜잭션을 사용할 수 없습니다. –