当前位置: 首页 > news >正文

Spring Boot 中 @Transactional 解析

在 Spring Boot 开发中,@Transactional 注解是实现数据库事务管理的关键工具,它能有效确保数据操作的原子性、一致性、隔离性和持久性(ACID)。本文将详细介绍 @Transactional 的使用方法、核心属性、原理以及常见的坑和解决方案。

一、@Transactional 的基本使用

@Transactional 注解可以应用在类或方法上。当标注在类上时,该类中的所有公共方法都会被纳入事务管理;若标注在方法上,则仅对该方法进行事务管理。

使用时,首先要在 Spring Boot 启动类上添加 @EnableTransactionManagement 注解,以开启事务管理功能。例如:

@SpringBootApplication
@EnableTransactionManagement
public class YourApplication {public static void main(String[] args) {SpringApplication.run(YourApplication.class, args);}
}

然后在需要事务管理的 Service 类或方法上添加 @Transactional 注解。如下所示:

@Service
public class UserService {private final UserRepository userRepository;public UserService(UserRepository userRepository) {this.userRepository = userRepository;}@Transactionalpublic void createUser(User user) {userRepository.save(user);// 假设这里还有其他数据库操作// 如果任何操作失败,整个事务将回滚}
}
二、@Transactional 的核心属性
  • propagation:事务传播行为,定义了被调用方法的事务边界,默认值为 Propagation.REQUIRED。常见取值有 Propagation.REQUIRED(若当前有事务则加入,无则创建新事务)、Propagation.REQUIRES_NEW(创建新事务,挂起当前事务)、Propagation.SUPPORTS(有事务则加入,无则以非事务方式执行)等。
  • isolation:事务隔离级别,用于解决事务并发访问时的问题,默认值为 Isolation.DEFAULT。如 Isolation.READ_UNCOMMITTED(允许读取未提交数据,可能出现脏读等)、Isolation.READ_COMMITTED(只允许读取已提交数据,可避免脏读)等。
  • timeout:事务的超时时间,单位为秒,默认值为 - 1,表示无超时限制。
  • rollbackFor:指定需要回滚的异常类型数组,默认情况下,只有运行时异常和错误会导致事务回滚。
  • noRollbackFor:指定不需要回滚的异常类型数组。
三、@Transactional 的原理

@Transactional 注解的逻辑是通过动态代理来实现的。Spring Boot 会先扫描 spring - boot - autoconfigure 依赖包下的 META - INF/spring.factories,加载 TransactionAutoConfiguration 类,再经过一系列解析和加载操作,最终向 Spring 容器注册事务相关的切面逻辑,主要涉及 Pointcut(确定哪个类需要增强)、Advise(具体的事务处理逻辑,如根据异常进行提交或回滚)和 Advisor(封装 Pointcut 和 Advise)。然后根据切面逻辑,利用 JDK 或 CGLIB 生成动态代理类,当调用被 @Transactional 注解标注的方法时,实际上是通过代理类来处理事务。

四、@Transactional 常见陷阱及解决方案
  • 事务失效
    • 自调用陷阱:同一类中方法 A 调用带 @Transactional 的方法 B,事务未生效,因为 Spring 事务基于 AOP 代理实现,自调用会绕过代理。可将方法 B 移到另一个 Service 类中,或通过 AopContext.currentProxy () 调用(需开启 @EnableAspectJAutoProxy (exposeProxy = true))。
    • 异常被 “吞没”:默认只回滚 RuntimeException 和 Error,若捕获异常未重新抛出或抛出受检异常,事务不会回滚。可通过 @Transactional (rollbackFor = Exception.class) 明确指定回滚异常,或在 catch 块中抛出 RuntimeException。
    • 访问权限限制:@Transactional 标注在 private 或 protected 方法上无效,因为 Spring AOP 代理要求目标方法为 public。可将方法改为 public,或使用 AspectJ 模式。
  • 传播机制配置不当:例如在日志记录方法中误用 Propagation.REQUIRED,会导致业务事务回滚时日志也被回滚。应根据实际需求选择合适的传播行为,如日志记录方法可使用 Propagation.REQUIRES_NEW。
  • 隔离级别问题:默认隔离级别可能导致不可重复读等问题。可根据业务需求升级隔离级别,如使用 @Transactional (isolation = Isolation.REPEATABLE_READ),或结合悲观锁等机制优化。

总之,@Transactional 在 Spring Boot 事务管理中起着重要作用,了解其使用方法和原理,注意避开常见陷阱,才能更好地确保数据的一致性和完整性,提升系统的稳定性和可靠性。

http://www.lryc.cn/news/617212.html

相关文章:

  • 自动化备份全网服务器数据平台项目
  • P2865 [USACO06NOV] Roadblocks G
  • ListNode* dummy = new ListNode();什么意思
  • 【功能测试】软件集成测试思路策略与经验总结
  • 使用纯NumPy实现回归任务:深入理解机器学习本质
  • 小结: getSpringFactoriesInstances从 `spring.factories` 文件中加载和实例化指定类型的类
  • 一维码+二维码+字符识别
  • 关于开发面对颠覆性需求变更的思考
  • SpringBoot 实现 Excel 导入导出功能的三种实现方式
  • MySQL语句,体系结构等基础知识解析
  • 量子计算:叩响金融定价革命的大门——期权定价的范式转移
  • 【PyTorch学习笔记 - 01】 Tensors(张量)
  • MLAG双活网络妙招:BGP + 静态VRRP实现智能负载均衡
  • MATLAB实现遗传算法求解路网路由问题
  • 【FAQ】Win11创建资源不足绕开微软账号登录
  • 【数据结构入门】树
  • 2025世界机器人大会|具身智能机器人十大发展趋势
  • 人脸识别系统技术文档
  • C9800 ISSU升级
  • Netty使用CA证书实现tls双认证
  • Linux ethernet驱动移植之常见问题
  • html转成markdown(1.0.0)
  • Mybatis学习之缓存(九)
  • 文件编辑html
  • 通用 maven 私服 settings.xml 多源配置文件(多个仓库优先级配置)
  • Django配置sqllite之外的数据库
  • 爬虫与数据分析结合案例学习总结
  • Apache Ignite 核心组件:GridClosureProcessor解析
  • pom.xml父子模块配置
  • 【Maven】01 - 入门篇