@Override
@Transactional(transactionManager="db1PlatformTransactionManager", propagation= Propagation.REQUIRED_NEW, rollbackFor = {InsufficientFundsException.class, EntityNotFoundException.class}, isolation=Isolation.READ_COMMITTED)
public Account creditAmount(AccountDto accountDto, BigDecimal creditAmt) throws EntityNotFoundException{
throw new EntityNotFoundException(Account.class, "accountNumber", accountDto.getAccountNumber().toString());
}
@Override
@Transactional(transactionManager="db1PlatformTransactionManager", propagation= Propagation.REQUIRED_NEW, rollbackFor = {InsufficientFundsException.class, EntityNotFoundException.class}, isolation=Isolation.READ_COMMITTED)
public Account debitAmount(AccountDto accountDto, BigDecimal debitAmt) throws EntityNotFoundException, InsufficientFundsException {
assert(debitAmt.compareTo(BigDecimal.ZERO) == 1); //assert greater than 0
Optional<Account> accountInDb = accountRepository.findById(accountDto.getAccountNumber());
if (accountInDb.isPresent()) {
Account account = accountInDb.get();
account.debit(debitAmt);
return accountRepository.save(account);
}
throw new EntityNotFoundException(Account.class, "accountNumber", accountDto.getAccountNumber().toString());
}
@Override
@Transactional(transactionManager="db1PlatformTransactionManager", propagation=Propagation.REQUIRED, rollbackFor = {InsufficientFundsException.class, EntityNotFoundException.class}, isolation=Isolation.READ_COMMITTED)
public List<Account> transferFunds(AccountDto debitAccountDto, AccountDto creditAccountDto, BigDecimal amount) throws EntityNotFoundException, InsufficientFundsException {
assert(amount.compareTo(BigDecimal.ZERO) == 1); //assert greater than 0
Account debitAccount = debitAmount(debitAccountDto, amount);
Account creditAccount = creditAmount(creditAccountDto, amount); // throws exception
return Stream
.of(debitAccount, creditAccount)
.collect(Collectors.toList());
}
如您所见,creditAmount方法抛出异常,而debitAmount方法的PRAPOGATION为REQUIRED_NEW。因此除外,因为debitAmount应该提交数据,但它也会回滚
答案 0 :(得分:0)
如此处所述: Spring使用同一个类中的事务来代理您的方法,因此调用同一个类的嵌套方法将不会通过拦截器,而是直接通过您自己的实例,这会导致您失去所有事务支持。
为避免这种情况,您可以通过两个步骤使用自我代理:
第1步:创建您当前服务的代理并将其注入其他任何bean 第2步:对于内部方法,请使用在第一步中创建的proxyBean。它应该像这样:
//@Autowired
//or instancied by your constructror
private YourCurrentService selfProxified;
@Override
@Transactional(transactionManager="db1PlatformTransactionManager", propagation=Propagation.REQUIRED, rollbackFor = {InsufficientFundsException.class, EntityNotFoundException.class}, isolation=Isolation.READ_COMMITTED)
public List<Account> transferFunds(AccountDto debitAccountDto, AccountDto creditAccountDto, BigDecimal amount) throws EntityNotFoundException, InsufficientFundsException {
assert(amount.compareTo(BigDecimal.ZERO) == 1); //assert greater than 0
Account debitAccount = selfProxified.debitAmount(debitAccountDto, amount);
Account creditAccount = selfProxified.creditAmount(creditAccountDto, amount); // throws exception
return Stream
.of(debitAccount, creditAccount)
.collect(Collectors.toList());
}