Spring @Transactional 注解

Spring @Transactional 注解深度解析

@Transactional 是 Spring 框架中用于声明式事务管理的核心注解,它简化了数据库事务的操作,让开发者能够以声明的方式控制事务边界。以下是该注解的全面解析:

1. 基本用法

java 复制代码
@Transactional
public void transferMoney(Long fromId, Long toId, BigDecimal amount) {
    // 业务逻辑
    accountRepository.debit(fromId, amount);
    accountRepository.credit(toId, amount);
}

2. 核心属性配置

属性名 说明 默认值
propagation 事务传播行为 REQUIRED
isolation 事务隔离级别 DEFAULT(数据库默认)
timeout 事务超时时间(秒) -1(不超时)
readOnly 是否只读事务 false
rollbackFor 触发回滚的异常类型 RuntimeException和Error
noRollbackFor 不触发回滚的异常类型 无

3. 事务传播行为(Propagation)

java 复制代码
@Transactional(propagation = Propagation.REQUIRED)
  • REQUIRED(默认):如果当前存在事务,则加入该事务;如果不存在,则新建一个事务
  • SUPPORTS:如果当前存在事务,则加入该事务;如果不存在,则以非事务方式执行
  • MANDATORY:必须在一个已有的事务中执行,否则抛出异常
  • REQUIRES_NEW:新建事务,如果当前存在事务,则挂起当前事务
  • NOT_SUPPORTED:以非事务方式执行,如果当前存在事务,则挂起当前事务
  • NEVER:以非事务方式执行,如果当前存在事务,则抛出异常
  • NESTED:如果当前存在事务,则在嵌套事务内执行;否则新建事务

4. 事务隔离级别(Isolation)

java 复制代码
@Transactional(isolation = Isolation.READ_COMMITTED)
  • DEFAULT:使用底层数据库的默认隔离级别
  • READ_UNCOMMITTED:读未提交(可能发生脏读、不可重复读和幻读)
  • READ_COMMITTED:读已提交(防止脏读,但可能发生不可重复读和幻读)
  • REPEATABLE_READ:可重复读(防止脏读和不可重复读,可能发生幻读)
  • SERIALIZABLE:串行化(最高隔离级别,防止所有并发问题)

5. 实现原理

Spring 通过 AOP(面向切面编程) 实现 @Transactional 的功能:

  1. 代理机制:

    • 对带有 @Transactional 注解的类/方法,Spring 会生成代理对象
    • 使用 JDK 动态代理(基于接口)或 CGLIB(基于类继承)
  2. 事务拦截器:

    • TransactionInterceptor 负责拦截方法调用
    • 在方法执行前开启事务,执行后提交或回滚事务
  3. 事务管理器:

    • 实际事务操作委托给 PlatformTransactionManager 实现
    • 如 DataSourceTransactionManager(JDBC)、JpaTransactionManager(JPA)等

6. 使用注意事项

  1. 生效条件:

    • 必须作用于 public 方法 上
    • 同一个类内部方法调用不会触发事务(因绕过代理)
    • 需要配置 @EnableTransactionManagement(Spring Boot 已自动配置)
  2. 常见问题:

    • 自调用失效:类内部方法A调用方法B,B的事务注解不生效
    java 复制代码
    public class AccountService {
        public void A() {
            this.B(); // 事务不生效
        }
        
        @Transactional
        public void B() {
            // ...
        }
    }
    • 异常捕获:在方法内捕获异常而未重新抛出,会导致事务无法回滚
    • 多数据源:需要为每个数据源配置独立的事务管理器
  3. 最佳实践:

    • 明确指定 rollbackFor 属性
    • 避免在事务方法中进行远程调用或耗时操作
    • 合理设置事务超时时间
    • 只读查询使用 readOnly=true 提升性能

7. 与其他技术的整合

  1. 与 JPA/Hibernate 整合:

    • 配置 JpaTransactionManager
    • 事务内会自动处理 Session 的开启和关闭
  2. 与 Spring Data JPA:

    • Repository 接口方法默认已有 @Transactional
    • 自定义方法可覆盖默认事务配置
  3. 分布式事务:

    • 对于跨库/跨服务场景,可结合 JTA 或 Seata 等分布式事务解决方案
    • @Transactional 本身不支持跨数据源事务

@Transactional 注解极大简化了事务管理,但理解其底层机制对于处理复杂事务场景至关重要。合理配置传播行为和隔离级别,可以解决大多数并发数据访问问题。

相关推荐
dishugj11 分钟前
oracle日志切换三条命令区别
数据库
Patrick在香港25 分钟前
一个斜杠,把毫秒变成十几秒
android·数据库·python·性能优化·正则表达式·回溯·redos
悟道书生31 分钟前
(一)Navicate为什么转存结构和数据只转存表而不包含建库?
数据库·oracle
赤龙ERP1 小时前
ERP周报:连接器开闸、国产GPU进场与智能工厂253家
数据库·人工智能·大模型·rpa·erp·企业数字化·builderpattern
lusklusklusk1 小时前
SQL Server补丁版本号为什么“日期新反而版本低”?——GDR、CU、CU+GDR 版本号规则与升级路径详解
数据库
key_3_feng1 小时前
评估与对齐:Agent 自我进化的护栏
前端·数据库·agent
TangGeeA1 小时前
数据库、SQL 与 DB AI
数据库·人工智能·sql
IvorySQL2 小时前
开源数据库进校园| 11 月 3 日,IvorySQL 校园行走进浙大宁波校区:从 PostgreSQL 扩展生态到 AI 实战
数据库·postgresql·开源
福建佰胜张工2 小时前
深度解析 Allen-Bradley 150-B135NBDA 智能电机控制器:选型、参数与工业应用
运维·数据库·单片机·嵌入式硬件·安全·自动化
`Levie2 小时前
MySQL-数据库服务日志管理与数据闪回
数据库·mysql