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());
        }
上一篇下一篇

猜你喜欢

热点阅读