目录
异常捕获处理
案例代码:
@Transactional
public void update(Integer from, Integer to, Double money) {
try {
//转账的用户不能为空
Account fromAccount = accountDao.selectByld(from);
//判断用户的钱是否够转账
if (fromAccount.getMoney() - money >= 0) {
fromAccount.setMoney(fromAccount.getMoney() - money);
accountDao.updateByld(fromAccount);
//异常
int a = 1 / 0;
//被转账的用户
Account toAccount = accountDao.selectByld(to);
toAccount.setMoney(toAccount.getMoney() + money);
accountDao.updateByld(toAccount);
}
} catch (Exception e) {
e.printStackTrace();
}
}
原因
事务通知只有捉到了目标抛出的异常,才能进行后续的回滚处理,如果目标自己处理掉异常,事务通知无法知悉
解决方法
在catch块添加throw new RuntimeException(e)抛出
抛出检查异常
案例代码:
@Transactional
public void update(Integer from, Integer to, Double money) throws FileNotFoundException {
//转账的用户不能为空
Account fromAccount = accountDao.selectByld(from);
//判断用户的钱是否够转账
if (fromAccount.getMoney() - money >= 0) {
fromAccount.setMoney(fromAccount.getMoney() - money);
accountDao.updateByld(fromAccount);
//读取文件
new FileInputStream("test");
//被转账的用户
Account toAccount = accountDao.selectByld(to);
toAccount.setMoney(toAccount.getMoney() + money);
accountDao.updateByld(toAccount);
}
}
原因
Spring 默认只会回滚非检查异常
解决方法
配置rollbackFor属性
@Transactional(rollbackFor=Exception.class)
非public方法
案例代码:
@Transactional
void update(Integer from, Integer to, Double money) {
//转账的用户不能为空
Account fromAccount = accountDao.selectByld(from);
//判断用户的钱是否够转账
if (fromAccount.getMoney() - money >= 0) {
fromAccount.setMoney(fromAccount.getMoney() - money);
accountDao.updateByld(fromAccount);
//被转账的用户
Account toAccount = accountDao.selectByld(to);
toAccount.setMoney(toAccount.getMoney() + money);
accountDao.updateByld(toAccount);
}
}
原因
Spring为方法创建代理、添加事务通知、前提条件都是该方法是public的
解决方法
改为public方法