TransactionTemplate 与@Transactional 注解的使用

TransactionTemplate编程式事务回滚 @Transactional(rollbackFor = Exception.class) public Boolean forceUpdateUserSkills(List<UserSkills> userSkills, Long userId) { //先删除用户的所有技能信息 return transactionTemplate.execute(new TransactionCallback<Boolean>() { 阅读详情
AI摘要

本文详细介绍了Spring框架中TransactionTemplate和@Transactional注解的使用方法和场景。TransactionTemplate是编程式事务管理工具,适用于动态或复杂事务逻辑;而@Transactional注解则用于声明式事务管理,可以作用于接口、类和方法上。文章还探讨了@Transactional注解的属性配置,以及在不同场景下可能导致@Transactional失效的原因和解决办法。

‌TransactionTemplate和@Transactional注解是Spring框架中实现事务管理的两种主要方式,各有其特点和适用场景。

TransactionTemplate的功能及方法

1. TransactionTemplate 功能

TransactionTemplate 是 Spring 提供的 编程式事务管理工具,通过代码显式控制事务的开启、提交和回滚,适用于需要动态或复杂事务逻辑的场景。

2. 核心方法及使用

(1) execute(TransactionCallback<T> action)

        功能:执行包含事务的代码块,支持返回值。

        代码示例:

public Boolean insertMarket(List<BenchmarkPriceDeviationRateIndex> infos){
        return transactionTemplate.execute(status -> {
            try {
                // 执行数据库操作等事务性操作,并返回结果
                if (infos != null && infos.size() > 0) {
                    try {
                        BenchmarkPriceDeviationRateIndex bo = new BenchmarkPriceDeviationRateIndex();
                        //删除源数据
                        mapper.deleteInfo(bo);
                        //批量插入数据
                        int ii = 0;
                        List<List<BenchmarkPriceDeviationRateIndex>> splitList1 =
                                (List<List<BenchmarkPriceDeviationRateIndex>>) ListUtils.splitList(infos, 800);
                        if (splitList1 != null) {
                            for (List<BenchmarkPriceDeviationRateIndex> ss : splitList1) {
                                long time41 = System.currentTimeMillis();
                                int i = mapper.batchInsert(ss);
                                ii += i;
                                long time42 = System.currentTimeMillis();
                                log.info("::::::::::::::一次800条插入数据耗时:::::::::::::" + (time42 - time41));
                            }
                        }
                    }catch (Exception e) {
                        e.printStackTrace();
                        // 异常处理,可以选择标记为回滚,并返回null或特定值表示失败状态
                        status.setRollbackOnly();
                    }
                }
                return true;
            } catch (Exception ex) {
                // 异常处理,可以选择标记为回滚,并返回null或特定值表示失败状态
                status.setRollbackOnly();
                return false; // 或者其他表示错误的值
            }
        });
}

(2) executeWithoutResult(Consumer<TransactionStatus> action)

功能:执行包含事务的代码块,支持返回值。

代码示例:

    public Boolean insertMarket(List<BenchmarkPriceDeviationRateIndex> infos){
//        无返回值写法
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                if (infos != null && infos.size() > 0) {
                    try {
                        BenchmarkPriceDeviationRateIndex bo = new BenchmarkPriceDeviationRateIndex();
                        //删除源数据
                        mapper.deleteInfo(bo);
                        //批量插入数据
                        int ii = 0;
                        List<List<BenchmarkPriceDeviationRateIndex>> splitList1 =
                                (List<List<BenchmarkPriceDeviationRateIndex>>) ListUtils.splitList(infos, 800);
                        if (splitList1 != null) {
                            for (List<BenchmarkPriceDeviationRateIndex> ss : splitList1) {
                                long time41 = System.currentTimeMillis();
                                int i = mapper.batchInsert(ss);
                                ii += i;
                                long time42 = System.currentTimeMillis();
                                log.info("::::::::::::::一次800条插入数据耗时:::::::::::::" + (time42 - time41));
                            }
                        }
                    }catch (Exception e) {
                        e.printStackTrace();
                        //事务回滚
                        transactionStatus.setRollbackOnly();
                    }
                }
            }
        });
    }

(3) 事务属性配置

可以通过设置传播行为和隔离级别来配置事务属性

传播行为:setPropagationBehavior()

// 新建独立事务(即使当前存在事务)
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);

隔离级别:setIsolationLevel()

//避免脏读,默认为ISOLATION_DEFAULT
transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT);

设置超时时间:setTimeout(int timeout); 设置事务的超时时间(以秒为单位)

        如果事务执行时间过长,可能会导致数据库锁争用或资源耗尽。可以通过 setTimeout 方法设置事务的超时时间。 

@Transactional使用

1、@Transactional注解可以作用于哪些地方

        @Transactional 可以作用在接口、类、类方法 

  • 作用于类:当把@Transactional 注解放在类上时,表示所有该类的public方法都配置相同的事务属性信息。

  • 作用于方法:当类配置了@Transactional,方法也配置了@Transactional,方法的事务会覆盖类的事务配置信息。

  • 作用于接口:不推荐这种使用方法,因为一旦标注在Interface上并且配置了Spring AOP 使用CGLib动态代理,将会导致@Transactional注解失效

2、@Transactional注解有哪些属性

propagation属性

propagation 代表事务的传播行为,默认值为 Propagation.REQUIRED,其他的属性信息如下:

  • Propagation.REQUIRED:如果当前存在事务,则加入该事务,如果当前不存在事务,则创建一个新的事务。( 也就是说如果A方法和B方法都添加了注解,在默认传播模式下,A方法内部调用B方法,会把两个方法的事务合并为一个事务 )

  • Propagation.SUPPORTS:如果当前存在事务,则加入该事务;如果当前不存在事务,则以非事务的方式继续运行。

  • Propagation.MANDATORY:如果当前存在事务,则加入该事务;如果当前不存在事务,则抛出异常。

  • Propagation.REQUIRES_NEW:重新创建一个新的事务,如果当前存在事务,暂停当前的事务。( 当类A中的 a 方法用默认Propagation.REQUIRED模式,类B中的 b方法加上采用 Propagation.REQUIRES_NEW模式,然后在 a 方法中调用 b方法操作数据库,然而 a方法抛出异常后,b方法并没有进行回滚,因为Propagation.REQUIRES_NEW会暂停 a方法的事务 )

  • Propagation.NOT_SUPPORTED:以非事务的方式运行,如果当前存在事务,暂停当前的事务。

  • Propagation.NEVER:以非事务的方式运行,如果当前存在事务,则抛出异常。

  • Propagation.NESTED :和 Propagation.REQUIRED 效果一样。

isolation 属性

isolation :事务的隔离级别,默认值为Isolation.DEFAULT

  • Isolation.DEFAULT:使用底层数据库默认的隔离级别。
  • Isolation.READ_UNCOMMITTED:读未提交
  • Isolation.READ_COMMITTED:读已提交
  • Isolation.REPEATABLE_READ:可重复读
  • Isolation.SERIALIZABLE:串行化

timeout 属性

timeout :事务的超时时间,默认值为 -1。如果超过该时间限制但事务还没有完成,则自动回滚事务。

readOnly 属性

readOnly :指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true。

rollbackFor 属性

rollbackFor :用于指定能够触发事务回滚的异常类型,可以指定多个异常类型。

noRollbackFor属性

noRollbackFor:抛出指定的异常类型,不回滚事务,也可以指定多个异常类型。

3、@Transactional失效场景与解决办法

1)@Transactional 应用在非 public 修饰的方法上

首先JDK动态代理肯定只能是public,因为接口的权限修饰符只能是public,所以其他的修饰符不可以使用,cglib代理的方式是可以代理protected方法的如果支持protected,大概率会造成当切换代理的实现方式时表现不同,所以会出现很多的bug,然后造成一系列的问题

 

之所以会失效是因为在Spring AOP 代理时,如上图所示 TransactionInterceptor (事务拦截器)在目标方法执行前后进行拦截,DynamicAdvisedInterceptor(CglibAopProxy 的内部类)的 intercept 方法或 JdkDynamicAopProxy 的 invoke 方法会间接调用 AbstractFallbackTransactionAttributeSource的 computeTransactionAttribute方法,获取Transactional 注解的事务配置信息。

AbstractFallbackTransactionAttributeSource类

protected TransactionAttribute computeTransactionAttribute(Method method,
    Class<?> targetClass) {
   
        // Don't allow no-public methods as required.
        if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
   
	return null;
        }

这个方法会检查目标方法的修饰符是不是 public,若不是 public,就不会获取@Transactional 的属性配置信息,最终会造成不会用 TransactionInterceptor 来拦截该目标方法进行事务管理。

2)@Transactional 注解属性 propagation 设置错误 

这种失效是由于配置错误,若是错误的配置以下三种 propagation,事务将不会发生回滚。

  • TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
  • TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
  • TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。

3)@Transactional 注解属性 rollbackFor 设置错误 

rollbackFor 可以指定能够触发事务回滚的异常类型。Spring默认抛出了未检查unchecked异常(继承自 RuntimeException 的异常)或者 Error才回滚事务;其他异常不会触发回滚事务。如果在事务中抛出其他类型的异常,但却期望 Spring 能够回滚事务,就需要指定 rollbackFor属性。

若在目标方法中抛出的异常是 rollbackFor 指定的异常的子类,事务同样会回滚。Spring源码如下

private int getDepth(Class<?> exceptionClass, int depth) {
        if (exceptionClass.getName().contains(this.exceptionName)) {
            // Found it!
            return depth;
}
        // If we've gone as far as we can go and haven't found it...
        if (exceptionClass == Throwable.class) {
            return -1;
}
return getDepth(exceptionClass.getSuperclass(), depth + 1);
}

 所以一般使用 @Transactional(rollbackFor = Exception.class) 就可以了

4)同一个类中方法调用,导致@Transactional失效

开发中避免不了会对同一个类里面的方法调用,比如有一个类Test,它的一个方法A,A再调用本类的方法B(不论方法B是用public还是private修饰),但方法A没有声明注解事务,而B方法有。则外部调用方法A之后,方法B的事务是不会起作用的。这也是经常犯错误的一个地方。

那为啥会出现这种情况?其实这还是由于使用Spring AOP代理造成的,因为只有当事务方法被当前类以外的代码调用时,才会由Spring生成的代理对象来管理。

错误入下:(但反过来(transactionalTest方法(@Transactional在transactionalTest方法上)调用Test方法)可以让@Transactional生效)

@RestController
@Slf4j
public class TestController {
    @Autowired
    UserService userService;

    @RequestMapping("/test")
    public void Test(){
        // 这里就相当于使用了 this.transactionalTest(); 使用的是本地对象的方法,没有用到spring容器,就无法触发AOP,导致事务失效
        transactionalTest();
    }
    
    @Transactional(rollbackFor = Exception.class)
    public void transactionalTest(){
        try {
            User user = new User().setName("张三");
            // 数据库操作
            userService.insertUser(user);
            // 手动设置异常
            int i = 1 / 0;
        } catch (Exception e) {
            log.error("执行事务异常,需要回滚",e);
            throw e;
        }
    }
}

解决方法:使用该类的Spring代理对象就可以了

1、AopContext.currentProxy()获得当前代理对象,注意:类上也需要加@EnableAspectJAutoProxy注解(==推荐==)

@RestController
@Slf4j
@EnableAspectJAutoProxy(proxyTargetClass = true,exposeProxy = true)
public class TestController {
    @Autowired
    UserService userService;



    @RequestMapping("/test")
    public void Test(){
        ((TestController) AopContext.currentProxy()).transactionalTest();
    }

    @Transactional(rollbackFor = Exception.class)
    public void transactionalTest(){
        try {
            User user = new User().setName("张三");
            // 数据库操作
            userService.insertUser(user);
            // 手动设置异常
            int i = 1 / 0;
        } catch (Exception e) {
            log.error("执行事务异常,需要回滚",e);
            throw e;
        }
    }
}

2、写到另一个类中使用@Autowired调用

3、实现ApplicationContextAware接口,获取Bean

@RestController
@Slf4j
public class TestController implements ApplicationContextAware {
    @Autowired
    UserService userService;

    private static ApplicationContext applicationContext;


    @RequestMapping("/test")
    public void Test(){
        TestController bean = applicationContext.getBean(TestController.class);
        bean.transactionalTest();
    }

    @Transactional(rollbackFor = Exception.class)
    public void transactionalTest(){
        try {
            User user = new User().setName("张三");
            // 数据库操作
            userService.insertUser(user);
            // 手动设置异常
            int i = 1 / 0;
        } catch (Exception e) {
            log.error("执行事务异常,需要回滚",e);
            throw e;
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        TestController.applicationContext = applicationContext;
    }
}

5)异常被你的 catch“吃了”导致@Transactional失效

AOP 可以说是生成一个代理类,可以在这个方法的头和尾添加代码,比如代理类使用一个try、catch把这个方法给套起来了,只有这个方法抛出异常之后,调用了代理类中catch的事务回滚代码才能回滚,所以你没抛出异常的话,@Transactional认为你是正常运行的代码所以不回滚

 

@Transactional(rollbackFor = Exception.class)
    public void transactionalTest(){
        try {
            User user = new User().setName("张三");
            // 数据库操作
            userService.insertUser(user);
            // 手动设置异常
            int i = 1 / 0;
        } catch (Exception e) {
            // 为啥写 catch ,还要写 throw e 抛出异常呢,因为要记日志啊,不记日志的话也可以不用,但哪个不写报错日志,出bug不是给自己挖坑吗
            log.error("执行事务异常,需要回滚",e);
            // 如果异常被 try 、 catch 吞了是不会回滚的
//            throw e;
        }
    }

 

 

Spring事务传播行为-编程式事务 Spring事务传播行为编程式事务 阅读详情

相关推荐

在同一个类中调用带有@Transactional注解的方法

需要注意的是,这种方式虽然可以实现事务的控制,但是需要手动管理事务,增加了代码的复杂度和维护成本。因此,建议将调用方法和被调用方法分开,使用 @Transactional 注解来管理事务,以便更好地维护和管理代码。在manageTransaction方法中,使用TransactionTemplate手动开启一个新的事务,并在事务中执行被调用的方法。但是,可以使用AspectJ的注解方式来实现事务的控制。需要注意的是,这种方式虽然可以保证事务生效,但是需要在同一个类中注入自己,不太符合面向对象的设计原则。

m0_73311735的博客 1112

TransactionTemplate编程式事务

TransactionTemplate学习相关记录

lyh59的博客 1万+

基于OpenCV的围棋终局识别与胜负判定系统实现

计算机视觉是人工智能领域的关键技术,它使计算机能够从数字图像或视频中获取、处理和分析信息。其核心原理在于通过图像处理算法提取特征,并基于这些特征进行识别、分类和测量。在工程实践中,计算机视觉技术为自动化、智能化应用提供了强大支持,广泛应用于工业检测、自动驾驶、医疗影像分析等领域。本文聚焦于一个具体的应用场景:利用OpenCV库实现围棋终局识别。通过图像预处理、棋盘检测与透视校正、交叉点定位等步骤,结合围棋规则逻辑,构建了一套从棋盘图像自动判定胜负的解决方案。该方案涉及自适应二值化、霍夫变换、连通域分析等关键

weixin_29100927的博客 280

Spring 中的编程式事务TransactionTemplate

编程式事务

weixin_36994098的博客 8249

FPGA实战:用Verilog实现Costas环载波同步(附Vivado2019.2仿真步骤)

本文详细介绍了如何在FPGA上使用Verilog实现Costas环载波同步,包括核心原理、Vivado2019.2工程配置、代码实现及仿真验证。通过正交下变频、相位误差检测和环路滤波等关键模块的设计,帮助开发者掌握数字通信系统中的载波同步技术,并提供了实用的调试和优化技巧。

k0l1m2n3o的博客 134

Python 实战:高效绕过 reCAPTCHA v3 的自动化策略

本文深入探讨了使用Python高效绕过reCAPTCHA v3验证的实战策略。文章首先解析了reCAPTCHA v3无感验证的评分机制,随后详细介绍了两种核心解决方案:一是利用CapSolver等专业API服务直接获取有效token,二是通过Playwright模拟真人浏览器行为以提升评分。文中提供了从定位关键参数到代码实现的完整流程,并强调了合规操作与请求频率控制的重要性,为自动化开发者提供了切实可行的技术指南。

weixin_29057065的博客 489

Spring Boot 中的 TransactionTemplate 是什么,如何使用

是Spring框架中的一个类,用于编程式地管理事务。它允许开发者在方法内定义事务范围,以确保在方法执行期间的数据库操作要么全部成功提交,要么全部回滚。提供了一种更灵活、更细粒度的事务控制方式,适用于各种场景。有时候,您可能需要自定义事务的逻辑,例如根据某些条件来决定是否提交或回滚事务。使用,您可以在execute方法内部编写自定义的逻辑,以满足特定需求。是Spring Boot中用于编程式事务管理的强大工具。它允许开发者更灵活地控制事务的边界,适用于多种应用场景,特别是需要细粒度控制事务的情况。通过。

IT徐师兄 1万+

Unity透明视频播放全攻略:AVPro Video插件实战与避坑指南

在游戏开发与交互式内容创作中,视频播放是常见的多媒体需求。其核心原理在于通过解码器将压缩的视频数据流转换为连续的图像帧,再经由图形API渲染至屏幕。这项技术的价值在于能够高效地呈现动态视觉内容,广泛应用于游戏过场动画、UI特效、AR/VR虚拟展示等场景。当需求进阶到需要背景透明的视频时,技术实现复杂度显著增加,这涉及到对视频Alpha通道的编码、解码与渲染管线的特殊处理。本文聚焦于Unity引擎中实现高质量透明视频播放的工程实践,深入解析了AVPro Video这一专业插件如何解决原生VideoPlayer

weixin_30368981的博客 376

TransactionTemplate 与@Transactional 注解的功能及方法详解

通过代码显式控制事务的开启、提交和回滚,适用于需要动态或复杂事务逻辑的场景。注解,通过 AOP 代理自动管理事务,简化事务配置,适合大多数场景。TransactionTemplate 是 Spring 提供的。是 Spring 提供的。

weixin_44343004的博客 2205

超声相控阵合成孔径成像FPGA设计介绍

1.仿真预览 2.理论分析 系统的基本结构如下所示: 以上是实际中完整的结构,系统中会涉及到两块板子中的时钟,这个就是设计一个时钟采样同步的问题,即所谓的时钟同步。一般这种情况,往往使用内插的方式来解决。这是由于,在实际中,超生波接收到的信号是由本身系统发送出去反射回来得到的,因此从另外一方面将,其是同步的。但是在接收的时候通过内插的方法解决其中的延迟问题。 根据论文中的介绍,整个系统分为如下几个部分: ·模拟发送信号,这个部分由MATLAB产生测试数据并量...

FPGA/MATLAB学习教程/源码/项目合作开发 2069

蓝牙协议栈详解(3)——BTstack

BTstack是一个轻量级蓝牙协议栈,支持经典蓝牙(BR/EDR)和低功耗蓝牙(BLE)。它采用事件驱动模型,可运行在MCU/CPU上,通过HCI接口与蓝牙控制器通信。协议栈包含完整的蓝牙协议层支持,如L2CAP、RFCOMM、ATT/GATT等,并提供丰富的示例代码。 主要特点包括模块化设计、开源授权、支持多种HCI传输方式(UART/USB)和操作系统适配。开发时需要关注事件驱动编程模型、内存配置优化、HCI传输稳定性等问题。典型应用场景包括SPP串口通信、BLE外设开发等。 使用建议从最小示例开始,逐

嵌入式软硬件叶玄 291

TransactionTemplate和@Transactional注解的区别

编程式事务和声明式事务的 区别

xiasiyu123456的博客 2208

手把手教你学PCIE(2.1.8)--pcie基本概念流量控制(Flow Control, FC)

PCIe 的流量控制(Flow Control, FC)是确保数据传输可靠性和高效性的关键技术。通过信用值管理,发送方和接收方可以动态调整数据传输速率,避免数据丢失和溢出。理解流量控制的工作原理和实现机制对于开发和调试 PCIe 系统非常重要。希望这个介绍能帮助你更好地理解和使用 PCIe 流量控制。

MHD0815的博客 1808

Spring中事务管理TransactionTemplate和@Transactional注解

1. Spring支持编程式事务管理TransactionTemplate和声明式事务管理@Transactional两种方式 和编程式事务相比,声明式事务唯一不足地方是最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。但是即便有这样的需求,也存在很多变通的方法,比如,可以将需要进行事务管理的代码块独立为方法等等(比如使用AopContext.currentProxy())。 2. @Transactional可通过AopContext.currentProxy()解决在同一个类

qq_40406380的博客 2955

【Tessy】集成测试小白入门指导

本文详细介绍了如何进行集成测试的小白入门指导,从新建工程到设计用例,实现集成测试的过程详细步骤

qq_37282365的博客 1187

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

使用 transactionManager和transactionTemplate管理事务

         transactionManager : 编程式事务.建立在AOP之上的。其本质是对方法前后进行拦截 .不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。    transactionTemplate : 编程式事务使用TransactionTemplate或者直...

m0_38068812的博客 4463

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

spring事物配置,编程式事务TransactionTemplate和基于声明式事务@Transactional注解的区别

事物管理对于企业应用来说是至关重要的,好使出现异常情况,它也可以保证数据的一致性。 spring支持编程式事务管理和声明式事务管理两种方式。 编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。 声明式事务...

luzhensmart的专栏 2228

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

混用 @Transactional 和 TransactionTemplate 被怼了,三种事务管理到底怎么选?

稍微总结一下。对于新手,建议先把的各种特性和坑点搞明白,基本能解决大部分问题。等到真正需要更精细控制的时候,再考虑其他方案。对于有经验的开发者,在已经熟练掌握编程时事务控制的前提下,再多关注事务的性能影响。事务不是万金油,过度使用或者不当使用都会带来不可预料的性能问题。最重要的是,无论选择哪种方式,都要保证代码的可读性和可维护性。技术是为业务服务的,而代码是要给整个团队一起维护的,不要为了炫技让代码变得晦涩难懂。希望这篇文章能帮你理清楚这三种方式的区别和使用场景。

sjkflw121150的博客 687

【Spring】事务(下):使用示例(编程式、声明式、注解式)

原文链接:https://blog.youkuaiyun.com/weixin_43935927/article/details/110943178 在 Spring 中使用事务有三种方式: 编程式:在开发代码中通过 TransactionTemplate 直接开启、提交、关闭事务 配置式:在 spring 配置文件中通过 tx 标签进行配置,然后借助 aop 实现 注解式:在配置文件开启注解,然后在选用使用事务的方法上 @Transactional 1.编程式事务管理 public class OrdersS.

A minor 607

springboot编程式事务TransactionTemplate的使用

总结:在类中注入TransactionTemplate,即可在springboot中使用编程式事务。 spring支持编程式事务管理和声明式事务管理两种方式。 编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。 声明式事务管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提

yzh_1346983557的博客 1万+

MyBatis 如何实现流式查询

目录 基本概念 MyBatis 流式查询接口 但构建 Cursor 的过程不简单 方案一:SqlSessionFactory 方案二:TransactionTemplate 方案三:@Transactional 注解 基本概念 流式查询指的是查询成功后不是返回一个集合而是返回一个迭代器,应用每次从迭代器取一条查询结果。流式查询的好处是能够降低内存使用。 如果没有流式查询,我们想要从数据库取 1000 万条记录而又没有足够的内存时,就不得不分页查询,而分页查询效率取决于表设计,如果设计的不好

琦彦 5622
上一篇: SpringBoot动态设置定时任务
下一篇: mybatis-plus-join-boot-starter依赖解决 Join 联表查询
Best_Liu~
博客等级 码龄7年 1万+粉丝 115原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值