事务场景中,抛出异常被catch后,如果需要回滚,一定要手动回滚事务

Posted miye

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了事务场景中,抛出异常被catch后,如果需要回滚,一定要手动回滚事务相关的知识,希望对你有一定的参考价值。

Spring使用声明式事务处理,默认情况下,如果被注解的数据库操作方法中发生了unchecked异常,所有的数据库操作将rollback;如果发生的异常是checked异常,默认情况下数据库操作还是会提交的。

checked异常:

表示无效,不是程序中可以预测的。比如无效的用户输入,文件不存在,网络或者数据库链接错误。这些都是外在的原因,都不是程序内部可以控制的。
必须在代码中显式地处理。比如try-catch块处理,或者给所在的方法加上throws说明,将异常抛到调用栈的上一层。

 

阿里编码规约示例:

 

Severity
   Major

Message
   事务场景中,抛出异常被catch后,如果需要回滚,一定要手动回滚事务。

Examples
   
Positive example 1/**
     * @author caikang
     * @date 2017/04/07
     */
    @Service
    @Transactional(rollbackFor = Exception.class)
    public class UserServiceImpl implements UserService {
        @Override
        public void save(User user) {
            //some code
            //db operation
        }
    }   
Positive example 2/**
     * @author caikang
     * @date 2017/04/07
     */
    @Service
    public class UserServiceImpl implements UserService {
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void save(User user) {
            //some code
            //db operation
        }
    }   
Positive example 3/**
     * @author caikang
     * @date 2017/04/07
     */
    @Service
    public class UserServiceImpl implements UserService {
        @Autowired
        private DataSourceTransactionManager transactionManager;

        @Override
        @Transactional
        public void save(User user) {
            DefaultTransactionDefinition def = new DefaultTransactionDefinition();
            // explicitly setting the transaction name is something that can only be done programmatically
            def.setName("SomeTxName");
            def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

            TransactionStatus status = transactionManager.getTransaction(def);
            try {
                // execute your business logic here
                //db operation
            } catch (Exception ex) {
                transactionManager.rollback(status);
                throw ex;
            }
        }
    }   

 

以上是关于事务场景中,抛出异常被catch后,如果需要回滚,一定要手动回滚事务的主要内容,如果未能解决你的问题,请参考以下文章

spring事物回滚机制 (事务异常回滚,捕获异常不抛出就不会回滚)

JPA事务中的异常最后不也抛出了,为什么没被catch到而导致回滚?

JPA事务中的异常最后不也抛出了,为什么没被catch到而导致回滚?

Spring 事务失效的几种场景

Spring 事务失效的几种场景

oracle断网后事务无法回滚