-1
@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());
}

as you see creditAmount method throws exception and debitAmount method have PRAPOGATION as REQUIRED_NEW. so excepted as debitAmount should commit data but it get rollback as well

  • Does this answer your question? [Spring - @Transactional - What happens in background?](https://stackoverflow.com/questions/1099025/spring-transactional-what-happens-in-background) – Julien Feb 21 '20 at 07:18

1 Answers1

0

As mentioned here : Spring proxify your method with transaction inside the same class, so calling a nested method of the same class will not go through the interceptor, but directly through your own instance, that lead you to lose all the transaction support.

TO avoid this you can go with a self proxy with two steps:

STEP 1: create a proxy of your current service and inject it as any other beans STEP 2: For internal method, use the proxyBean created in step one. it should look like:

  //@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());
  }
EFOE
  • 609
  • 1
  • 10
  • 20