0

0

Spring Boot 中 JPA 事务异常自动回滚的正确配置与实践

碧海醫心

碧海醫心

发布时间:2026-02-11 10:47:53

|

149人浏览过

|

来源于php中文网

原创

Spring Boot 中 JPA 事务异常自动回滚的正确配置与实践

本文详解 spring `@transactional` 注解在 jpa 场景下如何实现异常触发的自动事务回滚,明确说明无需显式配置 `rollbackfor` 即可对运行时异常生效,并强调 entitymanager 必须由 spring 管理才能保证事务一致性。

在 Spring Boot + JPA 应用中,确保数据库操作的原子性是事务管理的核心目标。你提供的代码使用了 @Transactional 注解,但内部包裹了 try-catch 并吞掉了异常(e.getCause() 未抛出或记录),这实际上破坏了 Spring 的事务回滚机制——因为 Spring 只有在方法非正常退出(即抛出未捕获异常) 时,才会将当前事务标记为 rollback-only。

✅ 正确做法:移除无效 try-catch,依赖默认回滚策略

Spring 的 @Transactional 默认行为是:当方法抛出任何未被捕获的 RuntimeException 或其子类(如 IllegalArgumentException、NullPointerException、JPA 的 PersistenceException 等)时,自动触发回滚。而 JDBC 操作失败(如 SQL 语法错误、约束冲突、连接中断)所抛出的异常,在 Spring Data JPA 中通常会被包装为 RuntimeException(例如 DataAccessException 的子类),因此无需额外指定 rollbackFor = Exception.class。

以下是重构后的推荐写法:

@Transactional
public void deleteDadosSExecReenvCancelada(Long nuSeqConsecao) {
    // 注意:不再使用 try-catch 包裹业务逻辑!

    String deleteReenvGruSql = """
        DELETE FROM sigpc_fnde.s_execucao_financ_gru_reenv 
        WHERE NU_SEQ_EXEC_FINANC_REENV IN (
            SELECT NU_SEQ_EXECUCAO_FINANCEIRA 
            FROM sigpc_fnde.s_exec_financ_reenv 
            WHERE NU_SEQ_CONCESSAO = ?
        )
        """;
    getEntityManager().createNativeQuery(deleteReenvGruSql)
                       .setParameter(1, nuSeqConsecao)
                       .executeUpdate();

    String deleteReenvSql = """
        DELETE FROM sigpc_fnde.s_exec_financ_reenv 
        WHERE NU_SEQ_CONCESSAO = ?
        """;
    getEntityManager().createNativeQuery(deleteReenvSql)
                       .setParameter(1, nuSeqConsecao)
                       .executeUpdate();
}

⚠️ 关键前提:EntityManager 必须由 Spring 托管

事务上下文与 EntityManager 生命周期强绑定。若 getEntityManager() 返回的是手动创建的 EntityManager(如通过 emf.createEntityManager()),则它脱离 Spring 的事务管理器(PlatformTransactionManager),即使加了 @Transactional,也无法实现回滚。

Hypotenuse AI
Hypotenuse AI

AI写作助手和文本生成器,根据关键词生成原创的、有洞察力的文章

下载

✅ 正确注入方式(推荐使用构造器注入 + @PersistenceContext):

@Service
@RequiredArgsConstructor
public class ExecucaoService {

    private final EntityManager entityManager; // Spring 自动注入受管 EntityManager

    @Transactional
    public void deleteDadosSExecReenvCancelada(Long nuSeqConsecao) {
        // ... 上述无 try-catch 的实现
    }
}
? 提示:@PersistenceContext 是 JPA 标准注解,Spring 会将其解析为容器管理的、与当前事务同步的 EntityManager 实例(即 SharedEntityManagerProxy),确保 flush、clear 和回滚行为均符合事务预期。

❌ 常见误区澄清

  • @Transactional(rollbackFor = Exception.class) 不是必须的:除非你明确需要对 IOException、SQLException 等检查型异常(checked exception)也触发回滚(此时需显式声明),否则默认策略已覆盖绝大多数 JPA 异常场景。
  • catch (Exception e) { e.getCause(); } 是危险模式:它吞噬异常、阻止传播,导致 Spring 认为方法“成功完成”,从而提交事务——即使第二条 DELETE 已失败,第一条也可能已被持久化。
  • 手动调用 entityManager.flush() 并非必需:executeUpdate() 本身不依赖一级缓存,直接执行 SQL;事务提交时自然保证所有变更原子生效或全部撤销。

✅ 最佳实践总结

项目 推荐方案
异常处理 避免空 catch;如需日志,应 log.error("删除执行信息失败", e); throw e;
事务边界 方法粒度合理,避免过长事务;必要时用 @Transactional(propagation = Propagation.REQUIRES_NEW) 隔离子流程
SQL 安全性 生产环境建议优先使用 JPQL 或 Repository 方法,原生 SQL 需严格校验表名/字段名及权限
测试验证 编写集成测试,主动模拟异常(如 mock EntityManager 抛出 PersistenceException),断言数据库状态未变更

遵循以上原则,你的 deleteDadosSExecReenvCancelada 方法即可在任意 SQL 执行失败时,自动、可靠地回滚整个事务,真正实现数据一致性保障。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

900

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

333

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

372

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

1550

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

368

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

1108

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

583

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

433

2024.04.29

Rust异步编程与Tokio运行时实战
Rust异步编程与Tokio运行时实战

本专题聚焦 Rust 语言的异步编程模型,深入讲解 async/await 机制与 Tokio 运行时的核心原理。内容包括异步任务调度、Future 执行模型、并发安全、网络 IO 编程以及高并发场景下的性能优化。通过实战示例,帮助开发者使用 Rust 构建高性能、低延迟的后端服务与网络应用。

1

2026.02.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号