0

I'm trying to do funds tranfer from Source Account to destination Account using JDBC declarative transaction and JDBC Template.

Use Case: If I try to call fundsTransfer method when source account does't have enough balance. In that case amount is getting added in destination account even though withdraw() throwing expected InSufficientFundsExceptions.

@Autowired
JdbcTemplate jdbcTemp;
-----
-----
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
public void deposit(int accountNumber, double amount) {
    String sql = "select Balance from <TableName> where Account_Number=?";
    double balance = jdbcTemp.queryForObject(sql, Double.class, accountNumber);
    balance = balance + amount;
    String sql2 = "update <TableName> set Balance=? where Account_Number=?";
    jdbcTemp.update(sql2, balance, accountNumber);
}

@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
public void withdraw(int accountNumber, double amount) throws InSufficientFundsExceptions {

    String sql = "select Balance from <TableName> where Account_Number=?";
    double balance = jdbcTemp.queryForObject(sql, Double.class, accountNumber);
    if (balance >= 5000) {
        balance = balance - amount;
        String sql2 = "update <TableName> set Balance=? where Account_Number=?";
        jdbcTemp.update(sql2, balance, accountNumber);
    } else {
        throw new InSufficientFundsExceptions("InSufficientFunds Exception");
    }
}

@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_COMMITTED)
public void fundsTransfer(int sourceAccountNumber, int destinationAccountNumber, double amount)
        throws InSufficientFundsExceptions {

    deposit(destinationAccountNumber, amount);
    withdraw(sourceAccountNumber, amount);
}

Note: If we call withdraw() before deposit() in fundsTranser, getting the expected exception.

Used Data Base - SQLServer

Could someone help me out here, what I'm missing here? Ideally, the reflected amount in destination account should get rollback because withdraw ends with an exception.

Kms
  • 1,082
  • 2
  • 11
  • 27
  • 4
    It appears `InSufficientFundsExceptions` is not a subclass of `RuntimeException`. If that is the case , use [`rollbackFor`](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/annotation/Transactional.html#rollbackFor--) to define the rollback behaviour for method `fundsTransfer()` – R.G May 24 '20 at 09:06
  • 1
    You may want to check [this answer](https://stackoverflow.com/a/39180354/13279831) to similar question – Nowhere Man May 24 '20 at 09:12

1 Answers1

1

The reason is because Spring by default only rolls back unchecked exceptions. Since your class is a checked exception because it does not extend runtimeException but regular Exception it doesn’t do a rollback.

You can Modify this behavior with the rollBackFor property in the @Transactional annotation and specifying insuffientFundsException.

Daniel Jacob
  • 1,455
  • 9
  • 17