Spring事务的坑你遇到过几个
有的小伙伴在开发过程中在Service方法上面加了一个@Transactional注解,就认为事务已经启动了,是真的
吗?
下面列出代码片段,所有的坑
事务都不好使,不信你试试。
完整代码获取gitee
坑一:调用私有方法
/**
* 调用私有方法,事务不好使
*/
public void saveUserCallPrivate() {
saveUserPrivate();
}
@Transactional()
private void saveUserPrivate(){
userMapper.insert(createUser());
throw new RuntimeException("saveUserPrivate");
}
坑二:调用this方法
/**
* 调用this.方法 事务也是不好用的
*/
public void saveUserCallThis() {
this.saveUserThis();
}
@Transactional()
public void saveUserThis(){
userMapper.insert(createUser());
throw new RuntimeException("saveUserThis");
}
坑二解决办法
@Autowired
private TransactionService self;
/**
* 这回就好使了
*/
public void saveUserCallSelf() {
self.saveUserThis();
}
@Transactional()
public void saveUserSelf(){
userMapper.insert(createUser());
throw new RuntimeException("saveUserSelf");
}
坑三:try-catch后,事务不好使
/**
* try-catch 后 事务不好使
*/
@Transactional()
public void saveUserWithTryCatch(){
try {
userMapper.insert(createUser());
throw new RuntimeException("saveUserWithTryCatch");
} catch (RuntimeException e) {
e.printStackTrace();
}
}
坑三解决办法
/**
* try-catch 后 事务不好使,手动回滚
*/
@Transactional()
public void saveUserWithTryCatchRight(){
try {
userMapper.insert(createUser());
throw new RuntimeException("saveUserWithTryCatch");
} catch (RuntimeException e) {
e.printStackTrace();
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
坑四:@Transactional()注解默认回滚是RuntimeException和Error
/**
* 默认是RuntimeException和Error
* @throws Exception
*/
@Transactional()
public void saveUserThrowException() throws Exception {
userMapper.insert(createUser());
throw new Exception("saveUserThrowException");
}
坑四解决办法
/**
* 默认是RuntimeException和Error,手动rollbackFor
* @throws Exception
*/
@Transactional(rollbackFor = Exception.class)
public void saveUserThrowExceptionRollbackFor() throws Exception {
userMapper.insert(createUser());
throw new Exception("saveUserThrowException");
}