Java-136 深入浅出 MySQL Spring Boot @Transactional 使用指南:事务传播、隔离级别与异常回滚策略

点一下关注吧!!!非常感谢!!持续更新!!!

🚀 AI篇持续更新中!(长期更新)

AI炼丹日志-31- 千呼万唤始出来 GPT-5 发布!"快的模型 + 深度思考模型 + 实时路由",持续打造实用AI工具指南!📐🤖

💻 Java篇正式开启!(300篇)

目前2025年09月22日更新到:
Java-130 深入浅出 MySQL MyCat 深入解析 核心配置文件 server.xml 使用与优化

MyBatis 已完结,Spring 已完结,Nginx已完结,Tomcat已完结,分布式服务正在更新!深入浅出助你打牢基础!

📊 大数据板块已完成多项干货更新(300篇):

包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余项核心组件,覆盖离线+实时数仓全栈!
大数据-278 Spark MLib - 基础介绍 机器学习算法 梯度提升树 GBDT案例 详解

注解参数

在 Transactional 注解中,定义了详细的内容。

value

value注解和transactionManager注解是相互的。

java 复制代码
/**
* Alias for {@link #transactionManager}.
* @see #transactionManager
*/
@AliasFor("transactionManager")
String value() default "";

transactionManager

value注解和transactionManager注解是相互的。

java 复制代码
@AliasFor("value")
String transactionManager() default "";

propagation

事务的传播类型

java 复制代码
	Propagation propagation() default Propagation.REQUIRED;

REQUIRED(默认)

  • 行为描述:如果当前存在事务,则加入当前的事务;如果没有就会新建一个事务
  • 应用场景:最常用的传播行为,适用于大多数业务场景
  • 示例:当ServiceA调用ServiceB时,如果ServiceA已开启事务,则ServiceB会加入该事务;否则ServiceB会新建事务

REQUIRES_NEW

  • 行为描述:无论当前是否有事务,总是新建一个事务
  • 特点:新事务会挂起当前事务(如果存在)
  • 应用场景:需要独立于当前事务执行的业务逻辑,如日志记录、审计等
  • 示例:支付主流程中需要记录操作日志,即使支付失败也要保留日志记录

SUPPORTS

  • 行为描述:支持当前事务,如果没有事务也可以正常执行
  • 特点:不会主动开启事务
  • 应用场景:查询操作或非核心业务逻辑
  • 示例:获取用户信息的服务方法,可以在事务中调用,也可以单独调用

NOT_SUPPORTED

  • 行为描述:不支持事务,执行时挂起任何现有的事务
  • 特点:以非事务方式执行
  • 应用场景:不需要事务支持的操作,如某些性能敏感的批量处理
  • 示例:大数据量的报表生成,不需要事务保证

MANDATORY

  • 行为描述:必须在一个现有事务中运行,否则会抛出异常
  • 特点:强制要求调用方必须开启事务
  • 应用场景:必须参与事务的关键业务逻辑
  • 示例:资金转账操作必须在一个事务中执行

NEVER

  • 行为描述:不允许在事务中运行,否则会抛出异常
  • 特点:强制要求无事务环境
  • 应用场景:特殊场景下需要确保不在事务中执行的方法
  • 示例:某些与事务冲突的特殊操作

NESTED

  • 行为描述:如果当前存在事务,则嵌套在该事务中
  • 特点
    • 可以设置保存点,部分回滚
    • 外层事务回滚会导致内层事务回滚
    • 内层事务回滚不会影响外层事务
  • 应用场景:复杂业务中需要部分回滚的场景
  • 示例:订单处理中的子项处理,某个子项失败只需回滚该子项,不影响其他子项

isolation

设置事务的隔离级别,以控制事务之间的干扰。

java 复制代码
	Isolation isolation() default Isolation.DEFAULT;

● DEFAULT:使用数据库默认的隔离级别。不同数据库的默认级别不同,例如MySQL默认为REPEATABLE_READ,Oracle默认为READ_COMMITTED,SQL Server默认为READ_COMMITTED。

● READ_UNCOMMITED(读未提交):

  • 最低的隔离级别
  • 允许读取其他事务未提交的修改(脏读)
  • 典型问题场景:
    • 事务A修改数据但未提交,事务B读取到未提交数据
    • 如果事务A回滚,事务B读取的就是无效数据
  • 性能最好但数据一致性最差

● READ_COMMITTED(读已提交):

  • 只允许读取已提交的数据
  • 解决了脏读问题
  • 仍存在的问题:
    • 不可重复读:事务内两次读取同一数据可能结果不同
    • 幻读:事务执行过程中,其他事务插入了新记录
  • 大多数数据库的默认级别

● REPEATABLE_READ(可重复读):

  • 保证在事务内多次读取同一数据结果一致
  • 解决了不可重复读问题
  • 仍存在的问题:
    • 幻读:其他事务可能插入新记录
  • 实现方式:
    • 通常通过多版本并发控制(MVCC)实现
  • MySQL的默认隔离级别

● SERIALIZABLE(串行化):

  • 最高的隔离级别
  • 完全串行化执行事务
  • 解决所有并发问题:
    • 脏读
    • 不可重复读
    • 幻读
  • 缺点:
    • 性能最低
    • 可能导致大量锁等待
  • 适用场景:
    • 需要最高数据一致性的场景
    • 金融交易等关键业务

各隔离级别对比表:

隔离级别 脏读 不可重复读 幻读 性能
READ_UNCOMMITED 可能 可能 可能 最高
READ_COMMITTED 不可能 可能 可能
REPEATABLE_READ 不可能 不可能 可能
SERIALIZABLE 不可能 不可能 不可能

timeout

指定事务的超时时间,单位为秒,超过时间事务将被回滚。

java 复制代码
	int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;

readOnly

设置事务只读,主要用于查询方法,优化性能。只读事务中不能进行数据更新操作。

java 复制代码
	boolean readOnly() default false;

rollbackFor

指定哪些异常类型导致事务回滚,默认情况下,RuntimeException 和 Error 会导致回滚,而 checked exception 不会导致回滚。

java 复制代码
	Class<? extends Throwable>[] rollbackFor() default {};

rollbackForClassName

指定哪些异常类型导致事务回滚,默认情况下,RuntimeException 和 Error 会导致回滚,而 checked exception 不会导致回滚。

java 复制代码
	String[] rollbackForClassName() default {};

noRollbackFor

noRollbackFor 属性用于指定哪些异常类型不触发事务回滚机制,与 rollbackFor 属性形成互补关系。当方法抛出 noRollbackFor 指定的异常类型或其子类时,事务会继续提交而不会回滚。

主要特点

  1. 与rollbackFor相反rollbackFor定义需要回滚的异常,而noRollbackFor定义不需要回滚的异常
  2. 异常继承性:对指定异常的子类同样有效
  3. 默认行为:默认情况下,只有RuntimeException和Error会导致回滚

语法格式

java 复制代码
@Transactional(noRollbackFor = {IOException.class, SQLTimeoutException.class})
public void someMethod() {...}

典型应用场景

  1. 业务异常处理:当某些业务异常(如库存不足)需要正常完成事务流程时
  2. 可恢复异常:如网络超时异常,希望重试而非回滚
  3. 日志记录异常:记录日志失败的异常不应影响主事务

注意事项

  • 如果同时配置了rollbackFornoRollbackFor,后者优先级更高
  • 建议明确指定业务相关的异常类型,而不是依赖默认行为
  • 对checked exception需要显式声明才会生效

示例

java 复制代码
// 当抛出InventoryException时事务不会回滚
@Transactional(noRollbackFor = InventoryException.class)
public void processOrder(Order order) throws InventoryException {
    // 业务逻辑
    if(stock < order.getQuantity()){
        throw new InventoryException("库存不足");
    }
    // 其他操作
}

这个属性在需要精细控制事务行为的场景中特别有用,可以避免不必要的回滚操作影响系统性能或业务逻辑。

java 复制代码
	Class<? extends Throwable>[] noRollbackFor() default {};

noRollbackForClassName

noRollbackForClassName 是 Spring 事务管理中的一个配置属性,用于指定某些异常类型不会触发事务回滚。这个属性与 rollbackForClassName 的功能正好相反,可以用来定义特定的异常白名单。

详细说明

  1. 作用机制

    • 当方法抛出 noRollbackForClassName 中指定的异常或其子类时,事务将继续提交而不会回滚
    • 适用于业务中那些"可以接受的"异常情况,比如业务校验不通过等预期内的异常
  2. 配置方式

java 复制代码
   @Transactional(noRollbackForClassName = {"com.example.BusinessException", 
                                          "com.example.ValidationException"})
   public void someMethod() {
       // 方法实现
   }
  1. 典型应用场景

    • 业务校验失败(如用户输入不合法)
    • 预期的业务异常(如账户余额不足)
    • 需要记录日志但不需要回滚的异常情况
  2. 注意事项

    • 需要提供完整的异常类名(包括包路径)
    • 对于检查型异常(checked exception)默认不会导致回滚,通常不需要特别配置
    • rollbackFor/rollbackForClassName 配合使用时,后者优先级更高
  3. 示例对比

java 复制代码
   // 配置1:所有异常都回滚,除了BusinessException
   @Transactional(noRollbackForClassName = "com.example.BusinessException")

   // 配置2:默认只回滚RuntimeException,额外配置也回滚IOException
   @Transactional(noRollbackForClassName = "java.io.IOException")
  1. 替代方案
    在较新版本的 Spring 中,推荐使用 noRollbackFor 属性(基于 Class 对象而非字符串),可以获得编译时类型检查的优势:
java 复制代码
   @Transactional(noRollbackFor = {BusinessException.class, ValidationException.class})
java 复制代码
	String[] noRollbackForClassName() default {};
相关推荐
不剪发的Tony老师3 小时前
SQLE:一个全方位的SQL质量管理平台
数据库·sql
TDengine (老段)3 小时前
TDengine 时序函数 IRATE 用户手册
大数据·数据库·物联网·时序数据库·iot·tdengine
lixora3 小时前
postgres linux 环境psql 中文乱码处理
数据库
TDengine (老段)3 小时前
TDengine 时序函数 CSUM 用户手册
大数据·数据库·sql·物联网·时序数据库·iot·tdengine
Knight_AL3 小时前
Spring Cloud Gateway 实战:全局过滤器日志统计与 Prometheus + Grafana 接口耗时监控
spring boot·spring cloud·grafana·prometheus
摇滚侠4 小时前
在 Oracle SQL 中实现 `IF-ELSE` 逻辑 SQL 错误 [12704] [72000]: ORA-12704: 字符集不匹配
数据库·sql·oracle
tyxbiy2348 小时前
【微服务初体验】Spring Cloud+MySQL构建简易电商系统
mysql·spring cloud·微服务
微笑尅乐8 小时前
力扣350.两个数组的交集II
java·算法·leetcode·动态规划
lypzcgf8 小时前
Coze源码分析-资源库-删除数据库-后端源码-流程/核心技术/总结
数据库·go·coze·coze源码分析·智能体平台·ai应用平台·agent平台