springBoot service 事务注解@Transactional不起作用
分析:默认spring事务只在发生未被捕获的 RuntimeException 时才回滚。
spring aop 异常捕获原理:被拦截的方法需显式抛出异常,并不能经任何处理,这样aop代理才能捕获到方法的异常,才能进行回滚,默认情况下aop只捕获 RuntimeException 的异常,但可以通过配置来捕获特定的异常并回滚
换句话说在service的方法中不使用try catch 或者在catch中最后加上throw new runtimeexcetpion(),这样程序异常时才能被aop捕获进而回滚
解决办法:
1. 首先确认数据库支持事务。即为InnoDB。
情况一:若是要手动try catch的情况下
在service层方法的catch语句中增加:
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句,手动回滚,这样上层就无需去处理异常
情况二:抛出异常的情况下
方案一:手动回滚。给注解加上参数如:@Transactional(rollbackFor=Exception.class)
方案二:抛出异常 改为继承RuntimeException的异常。并且在service上
层要继续捕获这个异常并处理
展示情况二,方案一
@Service
public class UserServiceImpl implements UserService { {
@Autowired
private UserMapper userMapper;
@Transactional(rollbackFor=Exception.class)
@Override
public int insert(String name, Integer age) throws Exception{{
int k = -1;
userMapper.insert(name, age);
userMapper.insert(name + "1", age);
userMapper.insert(name + "2", age);
k = userMapper.insert(name + "3", age);
Integer.valueOf("a");//手动加入异常
userMapper.insert(name + "4", age);
}
}
大部分转载自:
http://blog.sina.com.cn/s/blog_3c658efe0102y1u8.html