0


Springboot 编程式事务

spring-boot 2.5.3版本
msyql

SpringBoot编程式事务,可以使用2种方式。

Spring模板方式调用TransactionTemplate

默认TransactionAutoConfiguration自动装配。使用时直接注入TransactionTemplate 使用
推荐使用
编写一个测试类,简单测试一下,测试一下异常报错,手动设置回滚状态。

@AutowiredprivateTransactionTemplate transactionTemplate;@TestvoidtemplateTest(){Object execute = transactionTemplate.execute(newTransactionCallback(){/**
             * @param transactionStatus 事务运行状态信息 是否是新事务、是否已被标记为回滚等
             * @return
             */@OverridepublicObjectdoInTransaction(TransactionStatus transactionStatus){Object result;try{
                    log.info("执行事务方法");TerminalUserConfig ter =newTerminalUserConfig();
                    ter.setId(RandomUtil.randomLong());
                    ter.setConfigKey(RandomUtil.randomString(5));
                    ter.setConfigValue(RandomUtil.randomString(5));
                    ter.setUserId(1L);
                    result = terminalUserConfigMapper.insertTerminalUserConfig(ter);// 手动设置异常int i =1/0;
                    log.info("正常执行完成");return result;}catch(Exception exception){
                    log.info("执行事务异常,需要回滚");
                    transactionStatus.setRollbackOnly();returnfalse;}}});}

控制台打印
在这里插入图片描述

简单源码分析

spring提供了TransactionCallback和子类TransactionCallbackWithoutResult。
TransactionCallback默认是带返回值的,子类实现则不带。可以根据实际情况来决定是否需要返回值。
在这里插入图片描述
查看TransactionTemplate的execute方法可以知道。默认doInTransaction方法是不需要手动设置回滚状态,只要有异常就会自动回滚。
但是手动设置回滚也是可以,AbstractPlatformTransactionManager会在commit方法中判断事务的状态,然后决定提交还是回滚。
在这里插入图片描述
所以至于是否要捕获异常,可以自行决定。既然已经封装了异常捕获回滚,建议还是抛异常即可。

Spring原始方式PlatformTransactionManager

PlatformTransactionManager核心事务管理器 ,用来管理事务,包含事务的提交,回滚。
TransactionDefinition 事务基础信息 超时时间、隔离级别、传播属性等
TransactionStatus 事务状态

@TestvoidmanageTest(){//事务基础信息 超时时间、隔离级别、传播属性等DefaultTransactionDefinition transDef =newDefaultTransactionDefinition();// 定义事务属性// 设置传播行为属性, 默认事务级别。 当前无事务则新建事务,已有事务则加入事务。
        transDef.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRED);// 获得事务状态TransactionStatus status = transactionManager.getTransaction(transDef);try{
            log.info("执行事务方法");TerminalUserConfig ter =newTerminalUserConfig();
            ter.setId(RandomUtil.randomLong());
            ter.setConfigKey(RandomUtil.randomString(5));
            ter.setConfigValue(RandomUtil.randomString(5));
            ter.setUserId(1L);// 数据库操作
            terminalUserConfigMapper.insertTerminalUserConfig(ter);//手动设置异常int i =1/0;
            transactionManager.commit(status);// 提交}catch(Exception e){
            log.info("执行事务异常,需要回滚");
            transactionManager.rollback(status);// 回滚}}

控制台打印
在这里插入图片描述
方法需要实施事务管理,我们首先需要在方法开始执行前启动一个事务,调用PlatformTransactionManager.getTransaction(…) 方法便可启动一个事务。创建并启动了事务之后,便可以开始编写业务逻辑代码,然后在适当的地方执行事务的提交或者回滚。

很明显这样原始的方式,事务管理的代码散落在业务逻辑代码中,破坏了原有代码的条理性,并且每一个业务方法都包含了类似的启动事务、提交/回滚事务的模板代码。也可以简单封装成工具类去调用。

所以推荐使用TransactionTemplate

应用场景

在声明式事务流行的当下,编程式事务很少在项目中出现。
编程式事务最大的优点就是灵活可控,缺点就是要手写要规范且麻烦。

  • 灵活控制复杂业务流程
  • 大事务拆分

声明式事务的最小粒度要作用在方法
一个方法被事务嵌套,那么就可能会在方法中加入一些如RPC远程调用、消息发送、缓存更新、文件写入等操作。
接口会因为处理超长而容易超时,引发调用方事务回滚或者方法内某些业务操作无法自动回滚

大事务的拆分,可以拆分成多个小事务,通过编程式事务来解决。

所以还是要灵活组合使用。不能全部都是声明式事务,可以适当的使用一些编程式事务。当项目中有些奇葩操作出现时,编程式事务就有用武之地了。

标签: spring boot java spring

本文转载自: https://blog.csdn.net/xieqj_0511/article/details/129277531
版权归原作者 清枫975 所有, 如有侵权,请联系我们删除。

“Springboot 编程式事务”的评论:

还没有评论