使用JDBC声明性事务时,事务没有被回滚。

9 浏览
0 Comments

使用JDBC声明性事务时,事务没有被回滚。

我正在尝试使用JDBC声明性事务和JDBC模板从账户转账到目标账户。

用例:如果在源账户余额不足时尝试调用fundsTransfer方法。在这种情况下,即使withdraw()抛出了预期的InSufficientFundsExceptions异常,金额仍然会添加到目标账户中。

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

注意:如果我们在fundsTranser中先调用withdraw()再调用deposit(),会得到预期的异常。

使用的数据库 - SQLServer

有人可以帮我看看,我错过了什么吗?理想情况下,目标账户中反映的金额应该回滚,因为withdraw以异常结束。

0
0 Comments

问题原因:问题出现的原因是因为Spring默认只回滚未检查的异常。由于您的类是一个已检查的异常,因为它不是扩展自RuntimeException而是普通的Exception,所以它不会回滚。

解决方法:您可以通过在注解中使用rollBackFor属性,并指定insuffientFundsException来修改此行为。

0