Spring中的事务问题记录
2020-12-17 本文已影响0人
从零开始的程序猿生活
问题:
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
try {
checkSomething();
}catch (CustomizeException e){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
if (e.getStatus() != 200){
throw new CustomizeException(e.getStatus(),e.getMsg(),e.getData());
}
}
在事务中这个操作造成的问题。
原因:默认spring事务只在发生未被捕获的 RuntimeExcetpion时才回滚。
上面的代码因为设置了事务回滚,但是现在的判断导致有可能不会显示的抛出异常所以会报错。
Spring中的@Transactional声明事务
原理:
用注解方式声明的事务是建立在AOP上的,本质是在方法执行前后就行拦截,然后在方法执行前加入一个事务,在执行后提交事务或者回滚事务。被拦截的方法必须显示的抛出异常,这样才能呗aop代理捕获并回滚事务,如果异常被处理,就无法就行回滚,会抛出异常。
缺点:
这个方式声明的事务的粒度是方法级别的(编程式事务粒度是可以到代码块的)。不过可以通过抽取方法单独建立事务来实现同样的效果。
问题解决:
在Service层不处理这个异常,把异常处理拿到Controller层中处理即可解决。
try {
checkSomething();
}catch (CustomizeException e){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
throw new CustomizeException(e.getStatus(),e.getMsg(),e.getData());
}