事务场景中,抛出异常被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;
            }
        }
    }   
时间: 2024-10-08 14:33:50

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

Spring事务管理只对出现运行期异常进行回滚

使用spring难免要用到spring的事务管理,要用事务管理又会很自然的选择声明式的事务管理,在spring的文档中说道,spring声明式事务管理默认对非检查型异常和运行时异常进行事务回滚,而对检查型异常则不进行回滚操作.那么什么是检查型异常什么又是非检查型异常呢?最简单的判断点有两个:1.继承自runtimeexception或error的是非检查型异常,而继承自exception的则是检查型异常(当然,runtimeexception本身也是exception的子类). 2.对非检查型类

k8s中helm安装部署,升级和回滚(chart,helm,tiller,StorageClass)

一.Helm介绍 helm是基于kubernetes 的包管理器.它之于 kubernetes 就如 yum 之于 centos,pip 之于 python,npm 之于 javascript 那 helm 的引入对于管理集群有哪些帮助呢? 更方便地部署基础设施,如 gitlab,postgres,prometheus,grafana 等 更方便地部署自己的应用,为公司内部的项目配置 Chart,使用 helm 结合 CI,在 k8s 中部署应用一行命令般简单 1.Helm用途 Helm把Kub

SAP 公司间STO场景中外向交货单过账后自动触发内向交货单功能的实现

如下STO,是从公司代码SZSP转入CSAS, 如下图示的内向交货单180018660.该内向交货单是在外向交货单80016325 发货过账的时候自动触发的, 如何实现这个功能? 1)定义输出类型(output type)SPED SPRO > Logistic Execution > Shipping > Basic Shipping Functions > Output Control > Output Determination > Maintain Output

关于调用方有事务,被调用的SP中也有事务,在嵌套SP中回滚代码的报错处理,好文推荐

SQL报错异常:Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 0. --首先明确一点,在SQL中开启事务时,Begin Tran时,@@TRANCOUNT会加1,Commit Tran时@@TRANCOUNT会减1,但是当ROLLBACK TRAN时会把@@TranCount直接设置

为什么mysql事务回滚后, 自增ID依然自增

事务回滚后,自增ID仍然增加,回滚后,自增ID仍然增加.比如当前ID是7,插入一条数据后,又回滚了.然后你再插入一条数据,此时插入成功,这时候你的ID不是8,而是9.因为虽然你之前插入回滚,但是ID还是自增了. 如果你认为自增ID不应该被事务化,那么其他事务不得不等待着,检查自增ID是被使用还是被回滚,这就导致阻塞. 比如下面的例子,A表使用自增ID. User 1 ------------ begin transaction insert into A ... insert into B ..

事务回滚后,自增ID仍然增加

回滚后,自增ID仍然增加. 比如当前ID是7,插入一条数据后,又回滚了.然后你再插入一条数据,此时插入成功,这时候你的ID不是8,而是9.因为虽然你之前插入回滚,但是ID还是自增了. 如果你认为自增ID不应该被事务化,那么其他事务不得不等待着,检查自增ID是被使用还是被回滚,这就导致阻塞.比如下面的例子,A表使用自增ID.User 1------------begin transactioninsert into A ...insert into B ...update C ...insert

springmvc mybatis 声明式事务管理回滚失效,(checked回滚)捕捉异常,传输错误信息

一.知识点及问题 后端框架: Spring .Spring mvc .mybatis 业务需求: client先从服务端获取用户大量信息到client,编辑完毕之后统一Post至服务端,对于数据的改动要么全成功,要么全失败,所以须要使用事务支持. 问题: 配置Spring声明式事务,运行中出现异常未回滚.从网上查询得到一開始是自己的配置出了问题,因为配置文件的载入顺序决定了容器的载入顺序导致Spring事务没有起作用. 详情例如以下: 因为採用的是SpringMVC. MyBatis,故统一採用

Spring事务异常回滚,捕获异常不抛出就不会回滚(转载) 解决了我一年前的问题

最近遇到了事务不回滚的情况,我还考虑说JPA的事务有bug? 我想多了.......    为了打印清楚日志,很多方法我都加tyr catch,在catch中打印日志.但是这边情况来了,当这个方法异常时候 日志是打印了,但是加的事务却没有回滚. 例:     类似这样的方法不会回滚 (一个方法出错,另一个方法不会回滚) : if(userSave){ try { userDao.save(user); userCapabilityQuotaDao.save(capabilityQuota); }

好记性不如烂笔头25-JAVA处理数据库事务(3) - 事务回滚点

在具体的工作中,有的事情需要被保持,不需要回滚,有的工作需要回滚,而这些逻辑,可以通过手动设置事务的回滚点. 1.用JAVA处理数据库事务的事务回滚点的准备 要有一个能够访问数据库的应用.下面的示例都基于ORACLE进行. create table ffm_account( id int primary key , name varchar(32), money int ); 测试数据: insert into ffm_account(id,name,money)values(1,'A',100