Java事务回滚详解以及常见误区

 更新时间:2025年09月10日 08:27:03   作者:轩辕龙儿  
事务是指是程序中一系列严密的逻辑操作,而且所有操作必须全部成功完成,否则在每个操作中所作的所有更改都会被撤消,这篇文章主要介绍了Java事务回滚详解以及常见误区的相关资料,需要的朋友可以参考下

一、什么是事务回滚?

事务回滚指的是:当执行过程中发生异常时,之前对数据库所做的更改全部撤销,数据库状态恢复到事务开始前的状态。这是数据库“原子性”原则的体现。

二、Spring 中的@Transactional默认行为

在 Spring 中,使用注解方式开启事务非常简单:

@Transactional
public void doSomething() {
    // 执行数据库操作
}

此时的默认行为是:

  • 事务会在方法成功执行后提交;
  • 遇到 RuntimeException 或 Error,会自动回滚;
  • 遇到 Checked Exception(即编译时异常),不会自动回滚。

例如:

@Transactional
public void test1() {
    throw new RuntimeException(); // ✅ 会回滚
}

@Transactional
public void test2() throws Exception {
    throw new Exception(); // ❌ 不会回滚
}

三、使用rollbackFor让事务回滚受检异常

如果你希望事务在任何异常发生时都回滚,包括受检异常,比如 IOExceptionSQLException,就需要显式指定:

@Transactional(rollbackFor = Exception.class)
public void test3() throws Exception {
    throw new Exception(); // ✅ 会回滚
}
  • rollbackFor 的值可以是一个或多个异常类;
  • 你可以根据需要选择只对某些异常类型回滚,其他的则不回滚。

四、rollbackFor和rollbackOn的区别

特性rollbackForrollbackOn
适用范围SpringJava EE / JTA
包名org.springframework.transaction.annotation.Transactionaljavax.transaction.Transactional
默认行为回滚RuntimeException不回滚任何异常
明确配置后可回滚任何指定异常可回滚任何指定异常

示例比较:

Spring 中的写法:

import org.springframework.transaction.annotation.Transactional;

@Transactional(rollbackFor = Exception.class)
public void springTransaction() throws Exception {
    throw new Exception("测试受检异常");
}

JTA(Java EE)中的写法:

import javax.transaction.Transactional;

@Transactional(rollbackOn = Exception.class)
public void jtaTransaction() throws Exception {
    throw new Exception("测试受检异常");
}

注意:使用的是不同的注解类,不能混用!

五、常见误区

❌ 误区1:以为所有异常都会触发事务回滚

Spring 默认只回滚 RuntimeException,不会回滚 Exception(受检异常)。这是导致事务未回滚的最常见原因。

❌ 误区2:以为@Transactional可以应用于任何方法

只有被 Spring 容器管理(即被 Spring 扫描并代理)的类中的 public 方法,@Transactional 才有效。如果你在 private 方法上加了注解,是不会生效的。

❌ 误区3:使用错误的注解类

Spring 和 JTA 的 @Transactional 注解来自不同的包,使用时务必导入正确:

  • Spring: org.springframework.transaction.annotation.Transactional
  • JTA: javax.transaction.Transactional

六、小结

常见问题与解决方式

问题默认行为解决方式
事务不回滚受检异常❌ 不回滚✅ 添加rollbackFor = Exception.class(Spring)或 rollbackOn = Exception.class(JTA)
事务注解不生效❌ 方法不是public,类未被 Spring 管理✅ 保证类被 Spring 扫描,方法为public
导入错误注解❌ 使用了错误的@Transactional 注解✅ 使用正确包名下的注解(见下表)

Spring 与 JTA 的@Transactional对比

特性SpringJTA(Java EE)
注解类全名org.springframework.transaction.annotation.Transactionaljavax.transaction.Transactional
默认回滚行为回滚RuntimeException,不回滚 Exception不回滚任何异常
控制参数rollbackFor, noRollbackForrollbackOn, dontRollbackOn
常见场景Spring Boot, Spring MVC 项目Java EE, Jakarta EE 应用服务器项目
建议用法用 Spring 的事务注解为主仅在 Java EE 项目中使用

七、结语

事务控制是保障系统数据一致性的重要手段,理解事务的回滚机制尤为重要。在实际开发中,推荐明确指定异常回滚策略,避免因受检异常不回滚而造成数据异常。

希望这篇文章能帮你在开发中更精准地使用 @Transactional,写出更健壮、可控的代码。

附:下面说说我经常见到的3种事务不回滚的产生原因:

(1)声明式事务配置切入点表达式写错了,没切中Service中的方法

(2)Service方法中,把异常给try catch了,但catch里面只是打印了异常信息,没有手动抛出RuntimeException异常

(3)Service方法中,抛出的异常不属于运行时异常(如IO异常),因为Spring默认情况下是捕获到运行时异常就回滚

到此这篇关于Java事务回滚详解以及常见误区的文章就介绍到这了,更多相关Java事务回滚内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • mybatis的test坑及解决(不等于‘‘ 且 不等于0)

    mybatis的test坑及解决(不等于‘‘ 且 不等于0)

    这篇文章主要介绍了mybatis的test坑及解决(不等于‘‘ 且 不等于0),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • 关于@JsonProperty,@NotNull,@JsonIgnore的具体使用

    关于@JsonProperty,@NotNull,@JsonIgnore的具体使用

    这篇文章主要介绍了关于@JsonProperty,@NotNull,@JsonIgnore的具体使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • java Zookeeper简述

    java Zookeeper简述

    ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。下面通过本文给大家分享java 中 zookeeper简单使用,需要的朋友参考下吧
    2021-09-09
  • Spring Boot 2.x基础教程之使用@Scheduled实现定时任务的方法

    Spring Boot 2.x基础教程之使用@Scheduled实现定时任务的方法

    在Spring Boot中编写定时任务是非常简单的事,下面通过实例介绍如何在Spring Boot中创建定时任务,实现每过5秒输出一个当前时间,感兴趣的朋友跟随小编一起看看吧
    2021-07-07
  • java使用泛型实现栈结构示例分享

    java使用泛型实现栈结构示例分享

    泛型是Java SE5.0的重要特性,使用泛型编程可以使代码获得最大的重用。由于在使用泛型时要指明泛型的具体类型,这样就避免了类型转换。本实例将使用泛型来实现一个栈结构,并对其进行测试
    2014-03-03
  • 关于idea中ssm框架的编码问题分析

    关于idea中ssm框架的编码问题分析

    在实际开发中需要将操作系统编码、文件编码、页面编码以及tomcat服务器编码保持一致,而tomcat在默认情况下是使用UTF-8,这就使得其打印的日志文件出现中文乱码,因此在一般情况下,只需要将tomcat服务器的编码改为GBK即可
    2021-06-06
  • Java基础语法:逻辑控制

    Java基础语法:逻辑控制

    下面小编就为大家带来一篇Java逻辑控制的基础文章。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2021-08-08
  • 教你怎么用java实现客户端与服务器一问一答

    教你怎么用java实现客户端与服务器一问一答

    这篇文章主要介绍了教你怎么用java实现客户端与服务器一问一答,文中有非常详细的代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下
    2021-04-04
  • 如何在java 8 stream表达式实现if/else逻辑

    如何在java 8 stream表达式实现if/else逻辑

    这篇文章主要介绍了如何在java 8 stream表达式实现if/else逻辑,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • jenkins 构建项目之 pipeline基础教程

    jenkins 构建项目之 pipeline基础教程

    ​pipeline ,简单来说,就是一套运行在 jenkins 上的工作流框架。这篇文章主要介绍了jenkins 构建项目之 pipeline基础教程,需要的朋友可以参考下
    2020-07-07

最新评论