SpringBoot 中的 @Transactional 事务基本作用及注意事项示例详解

 更新时间:2025年09月25日 10:03:35   作者:喝汽水的猫^  
@Transactional是SpringBoot中声明式事务管理的核心注解,通过注解简化事务控制,确保操作的原子性,支持异常回滚、隔离级别和传播行为配置,需注意代理模式、异常抛出及数据库支持等条件,避免事务失效,本文介绍SpringBoot @Transactional事务作用,感兴趣的朋友一起看看吧

前言

@Transactional 是 Spring 中用于声明式事务管理的核心注解,它可以简化事务控制逻辑,通过注解方式替代传统的编程式事务管理。在 Spring Boot 中,@Transactional 的使用尤为广泛,以下是其详细解析:

一、基本作用

@Transactional 用于标记某个方法或类需要被事务管理,Spring 会在方法执行前后自动开启、提交或回滚事务,确保操作的原子性(要么全成功,要么全失败)。

使用位置:

  • 方法上:仅对该方法生效
  • 类上:对类中所有公共方法生效(public)
  • 接口上:不推荐(可能因代理模式导致失效)

二、核心属性

@Transactional 有多个属性可配置,常用的包括:

属性名作用默认值
rollbackFor指定哪些异常触发回滚(类或数组)仅 RuntimeException 及其子类
noRollbackFor指定哪些异常不触发回滚
isolation事务隔离级别(控制并发数据可见性)Isolation.DEFAULT(数据库默认)
propagation事务传播行为(控制嵌套方法的事务归属)Propagation.REQUIRED
readOnly是否为只读事务(优化性能,适合查询操作)false
timeout事务超时时间(秒),超时后自动回滚-1(无超时)
value/transactionManager指定事务管理器(多数据源时使用)默认事务管理器

1. 异常回滚配置(rollbackFor/noRollbackFor)

  • 默认规则:仅对 RuntimeException 及其子类(非检查异常)回滚,对 Exception 及其子类(检查异常)不回滚。
  • 推荐配置:rollbackFor = Exception.class,确保所有异常都触发回滚:

示例:

@Transactional(rollbackFor = Exception.class) // 所有异常都回滚
public void saveData() throws Exception {
    // 业务逻辑
}
  • 特殊需求:指定不回滚的异常:

示例:

@Transactional(noRollbackFor = ArithmeticException.class)
public void process() {
    // 发生 ArithmeticException 不回滚,其他异常正常回滚
}

2. 隔离级别(isolation)

控制并发事务之间的数据可见性,可选值:

  • Isolation.DEFAULT:使用数据库默认隔离级别(推荐)
  • Isolation.READ_UNCOMMITTED:读未提交(最低隔离,可能脏读)
  • Isolation.READ_COMMITTED:读已提交(避免脏读,多数数据库默认)
  • Isolation.REPEATABLE_READ:可重复读(避免脏读、不可重复读,MySQL 默认)
  • Isolation.SERIALIZABLE:串行化(最高隔离,避免幻读,性能最低)

示例:

@Transactional(isolation = Isolation.READ_COMMITTED)
public void queryData() {
    // 事务内查询,只能看到已提交的数据
}

3.脏读(Dirty Read)

定义:一个事务读取到了另一个未提交事务修改的数据。

场景示例:

  • 事务 A:更新了一条记录但未提交
  • 事务 B:读取了事务 A 更新后的记录
  • 事务 A:由于某种原因回滚了操作
  • 结果:事务 B 读取到的数据是 “无效” 的(已被回滚)

危害:导致读取到临时且可能被撤销的数据,影响业务逻辑正确性。

避免方式:将事务隔离级别设置为 READ COMMITTED 或更高(REPEATABLE READ、SERIALIZABLE)。

MySQL 默认隔离级别是 REPEATABLE READ,已避免脏读。

4.幻读(Phantom Read)

定义:一个事务在两次查询中得到不同的结果集,因为另一个事务在两次查询之间插入或删除了数据。

场景示例:

  • 事务 A:查询年龄 > 20 的用户,得到 10 条记录
  • 事务 B:插入了一条年龄 = 25 的新用户并提交
  • 事务 A:再次执行相同查询,得到 11 条记录(多了一条 “幻影” 数据)

5. 传播行为(propagation)

控制嵌套方法的事务归属,核心值:

  • Propagation.REQUIRED(默认):如果当前有事务,则加入;否则新建事务。
  • Propagation.REQUIRES_NEW:无论当前是否有事务,都新建独立事务(原事务暂停)。
  • Propagation.SUPPORTS:如果当前有事务,则加入;否则以非事务方式执行。
  • Propagation.NOT_SUPPORTED:以非事务方式执行,若当前有事务则暂停。
  • Propagation.NEVER:必须在非事务环境执行,否则抛异常。
  • Propagation.MANDATORY:必须在事务环境执行,否则抛异常。
  • Propagation.NESTED:嵌套事务(依赖数据库支持,如 MySQL 的 SAVEPOINT)。

示例:独立事务场景

@Service
public class OrderService {
    @Autowired
    private LogService logService;
    @Transactional(rollbackFor = Exception.class)
    public void createOrder() {
        // 订单业务(主事务)
        logService.saveLog(); // 调用日志服务
    }
}
@Service
public class LogService {
    // 日志保存使用独立事务,即使订单回滚,日志仍会提交
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public void saveLog() {
        // 保存日志
    }
}

6. 其他属性

  • readOnly = true:适用于纯查询方法,数据库可优化性能(如避免写锁):
@Transactional(readOnly = true)
public List<User> queryUsers() {
    return userMapper.selectAll();
}
  • timeout = 10:事务超时时间 10 秒,超时后自动回滚:
@Transactional(timeout = 10)
public void longTimeTask() {
    // 长时间任务,超时会回滚
}

三、事务生效条件

1.代理模式:Spring 事务基于 AOP 代理实现,需满足:

  • 方法必须是 public(非 public 方法注解可能失效)。
  • 需通过 Spring 容器的代理对象调用方法(同类中自调用可能失效,需特殊处理)。

2.异常处理:

  • 异常必须抛出到 @Transactional 标记的方法外(被捕获的异常不会触发回滚)。
  • 需符合 rollbackFor 配置的异常类型。

3.数据库支持:

  • 数据库必须支持事务(如 MySQL 的 InnoDB 引擎,MyISAM 不支持)。

四、常见问题

1.自调用事务失效:

@Service
public class UserService {
    public void methodA() {
        methodB(); // 自调用,事务可能失效
    }
    @Transactional
    public void methodB() {
        // 业务逻辑
    }
}

解决:通过 Spring 上下文获取代理对象调用,或使用 @EnableAspectJAutoProxy(exposeProxy = true) 暴露代理。

2.多线程事务不共享:

新线程中的方法不会加入当前事务,需手动协调事务。

3.错误的异常处理:

@Transactional
public void save() {
    try {
        // 业务逻辑
    } catch (Exception e) {
        // 异常被捕获,未抛出,事务不会回滚
    }
}

解决:捕获后需重新抛出异常,或手动调用 TransactionStatus.setRollbackOnly()。

五、总结

@Transactional 是 Spring Boot 中简化事务管理的强大工具,核心关注:

  • 异常回滚规则(rollbackFor)
  • 并发控制(isolation)
  • 嵌套事务关系(propagation)
    合理配置可确保数据一致性,同时需注意代理模式、异常处理等细节避免事务失效。

到此这篇关于SpringBoot 中的 @Transactional 事务详解及注意事项的文章就介绍到这了,更多相关SpringBoot @Transactional 事务内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Springboot ApplicationRunner的使用解读

    Springboot ApplicationRunner的使用解读

    这篇文章主要介绍了Springboot ApplicationRunner的使用解读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • java servlet手机app访问接口(一)数据加密传输验证

    java servlet手机app访问接口(一)数据加密传输验证

    这篇文章主要为大家详细介绍了java servlet手机app访问接口(一),数据加密传输验证,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-12-12
  • Java使用ProcessBuilder API优化流程

    Java使用ProcessBuilder API优化流程

    Java 的 Process API 为开发者提供了执行操作系统命令的强大功能,这篇文章将详细介绍如何使用 ProcessBuilder API 来方便的操作系统命令,需要的可以收藏一下
    2023-06-06
  • Java通过jersey实现客户端图片上传示例

    Java通过jersey实现客户端图片上传示例

    本篇文章主要介绍了Java通过jersey实现客户端图片上传示例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-03-03
  • java中线程池的关闭问题

    java中线程池的关闭问题

    这篇文章主要介绍了java中线程池的关闭问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • java使用JDBC动态创建数据表及SQL预处理的方法

    java使用JDBC动态创建数据表及SQL预处理的方法

    这篇文章主要介绍了java使用JDBC动态创建数据表及SQL预处理的方法,涉及JDBC操作数据库的连接、创建表、添加数据、查询等相关实现技巧,需要的朋友可以参考下
    2017-08-08
  • myeclipse10配置tomcat教程详解

    myeclipse10配置tomcat教程详解

    这篇文章主要为大家详细介绍了myeclipse10配置tomcat的教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-07-07
  • Java去重排序之Comparable与Comparator的使用及说明

    Java去重排序之Comparable与Comparator的使用及说明

    这篇文章主要介绍了Java去重排序之Comparable与Comparator的使用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • 浅谈java分页三个类 PageBean ResponseUtil StringUtil

    浅谈java分页三个类 PageBean ResponseUtil StringUtil

    下面小编就为大家带来一篇浅谈java分页三个类 PageBean ResponseUtil StringUtil。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • java从命令行获取数据的三种方式代码实例

    java从命令行获取数据的三种方式代码实例

    这篇文章主要介绍了java从命令行获取数据的三种方式代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12

最新评论