SpringBoot手动提交/回滚事务实现方式

 更新时间:2026年05月17日 10:07:44   作者:一直到老到直一  
在SpringBoot中,推荐使用`@Transactional`注解进行声明式事务管理,但在某些情况下,可能需要手动控制事务,可通过`TransactionTemplate`或编程式事务管理来实现,涉及获取事务管理器、开始事务、执行操作、提交或回滚事务,通常建议使用声明式事务管理,除非有特殊需求

在Spring Boot中,通常推荐使用声明式事务管理(即使用@Transactional注解)来自动处理事务的开启、提交和回滚。然而,在某些情况下,可能需要更细致地控制事务的边界,这时可能需要手动提交或回滚事务。

虽然Spring Boot本身不直接提供“手动”提交或回滚事务的API(因为Spring的PlatformTransactionManager接口被设计为抽象层,隐藏了具体事务实现的细节),但可以通过操作底层资源(如TransactionTemplateTransactionStatus)或使用编程式事务管理来间接实现这一点。

使用TransactionTemplate

TransactionTemplate提供了一种模板方法,允许在回调中执行数据库操作,并且可以配置事务的属性(如隔离级别、传播行为等)。然而,它并不直接提供“手动”提交或回滚事务的API,因为它会在回调方法执行完毕后自动提交事务(如果没有抛出异常),或者在抛出异常时自动回滚事务。

下面是一个使用 TransactionTemplate 的示例:

首先,需要在 Spring 配置中定义 TransactionTemplate bean(如果使用的是基于 Java 的配置,可以通过 @Bean 注解来定义):

@Configuration  
@EnableTransactionManagement  
public class TransactionConfig {  
  
    @Autowired  
    private PlatformTransactionManager transactionManager;  
  
    @Bean  
    public TransactionTemplate transactionTemplate() {  
        return new TransactionTemplate(transactionManager);  
    }  
}

然后,在服务类中注入 TransactionTemplate 并使用它:

@Service  
public class YourService {  
  
    @Autowired  
    private TransactionTemplate transactionTemplate;  
  
    @Autowired  
    private YourRepository yourRepository; // 假设你有一个Repository  
  
    public void performDatabaseOperations() {  
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {  
            @Override  
            protected void doInTransactionWithoutResult(TransactionStatus status) {  
                try {  
                    // 在这里执行数据库操作  
                    yourRepository.saveSomething();  
                    // 可以继续执行其他数据库操作...  
  
                    // 如果一切正常,TransactionTemplate会自动提交事务  
                    // 不需要手动调用status.commit();  
  
                } catch (RuntimeException ex) {  
                    // 如果捕获到异常,可以选择回滚事务  
                    // 注意:在TransactionCallbackWithoutResult中,通常不需要显式调用status.rollback();  
                    // 因为TransactionTemplate默认会在回调方法抛出异常时回滚事务  
                    // 但如果你想在回滚之前执行一些清理操作,可以在这里处理  
                    // 然后重新抛出异常,让TransactionTemplate知道需要回滚  
                    throw ex; // 重新抛出异常  
                }  
            }  
        });  
    }  
}

编程式事务管理

如果确实需要更细粒度的控制,可以通过PlatformTransactionManager接口来编程式地管理事务。这通常涉及以下几个步骤:

  • 获取事务管理器:首先,需要获取PlatformTransactionManager的实例。这通常是通过依赖注入来完成的。
  • 开始事务:使用事务管理器的getTransaction方法开始一个新的事务,该方法返回一个TransactionStatus对象,该对象代表了当前事务的状态。
  • 执行数据库操作:在事务的上下文中执行你的数据库操作。
  • 提交或回滚事务:根据数据库操作的结果,可以调用TransactionStatus对象的commit方法来提交事务,或者在捕获到异常时调用rollback方法来回滚事务。

示例

以下是一个简单的示例,展示了如何在Spring Boot服务中编程式地管理事务:

@Service  
public class YourService {  
  
    @Autowired  
    private PlatformTransactionManager transactionManager;  
  
    @Autowired  
    private YourRepository yourRepository; // 假设你有一个Repository  
  
    public void yourMethod() {  
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();  
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);  
  
        TransactionStatus status = transactionManager.getTransaction(def);  
  
        try {  
            // 执行数据库操作  
            yourRepository.someDatabaseOperation();  
  
            // 提交事务  
            transactionManager.commit(status);  
        } catch (RuntimeException e) {  
            // 回滚事务  
            transactionManager.rollback(status);  
            throw e; // 可以选择重新抛出异常  
        }  
    }  
}

注意

虽然上述代码展示了如何在Spring Boot中编程式地管理事务,但在实际开发中,除非有特别的需求,否则通常建议使用声明式事务管理(即@Transactional注解),因为它更简单、更易于维护,并且与Spring的集成更加紧密。

此外,如果业务逻辑非常复杂,需要跨多个服务或方法边界控制事务,那么可能需要考虑使用分布式事务解决方案,如Spring Cloud Alibaba的Seata等。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Spring @Cacheable注解类内部调用失效的解决方案

    Spring @Cacheable注解类内部调用失效的解决方案

    这篇文章主要介绍了Spring @Cacheable注解类内部调用失效的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • springboot集成springsecurity 使用OAUTH2做权限管理的教程

    springboot集成springsecurity 使用OAUTH2做权限管理的教程

    这篇文章主要介绍了springboot集成springsecurity 使用OAUTH2做权限管理的教程,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • JAVA大作业之图书管理系统实现全解

    JAVA大作业之图书管理系统实现全解

    随着网络技术的高速发展,计算机应用的普及,利用计算机对图书馆的日常工作进行管理势在必行,本篇文章手把手带你用Java实现一个图书管理系统,大家可以在过程中查缺补漏,提升水平
    2022-01-01
  • Java实现指定目录下的文件查找详解

    Java实现指定目录下的文件查找详解

    这篇文章主要介绍了利用Java实现指定目录下的文件查找的方法,能做到给出文件名,查找目录及其子目录中是否存在或者给出后缀名,查找目录及其子目录中相关的文件,感兴趣的可以学习一下
    2022-03-03
  • Mybatis批量插入数据返回主键的实现

    Mybatis批量插入数据返回主键的实现

    这篇文章主要介绍了Mybatis批量插入数据返回主键的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01
  • 轻松掌握Java代理模式

    轻松掌握Java代理模式

    这篇文章主要帮助大家轻松掌握Java代理模式,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-09-09
  • Mybatis内置参数之_parameter和_databaseId的使用

    Mybatis内置参数之_parameter和_databaseId的使用

    这篇文章主要介绍了Mybatis内置参数之_parameter和_databaseId的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • 将Dubbo服务打包成Jar包的操作步骤

    将Dubbo服务打包成Jar包的操作步骤

    Dubbo 是一款流行的 Java RPC 框架,它提供了高性能、透明化的 RPC 远程服务调用方案,在开发基于 Dubbo 的服务时,我们通常需要将服务代码打包成可发布的 JAR 包,本文将详细介绍如何将 Dubbo 服务打包成 JAR 包,并提供相应的配置和步骤,需要的朋友可以参考下
    2024-12-12
  • java实现实时通信聊天程序

    java实现实时通信聊天程序

    这篇文章主要为大家详细介绍了java实现实时通信聊天程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • MybatisPlus查询条件空字符串和NULL问题背景分析

    MybatisPlus查询条件空字符串和NULL问题背景分析

    文章详细分析了MybatisPlus在处理查询条件时,空字符串和NULL值的问题,MP 3.3.0及以上版本提供了多种解决方法,包括在Bean属性上使用注解、全局配置等,推荐使用全局配置的方式来解决这个问题,以避免在SQL查询中出现不必要的空字符串条件,感兴趣的朋友跟随小编一起看看吧
    2025-03-03

最新评论