Spring事务管理深度解析:原理、实践与陷阱

Spring事务管理深度解析:原理、实践与陷阱

一、事务基础概念

ACID原则

  • 原子性(Atomicity):事务内的操作要么全部成功,要么全部回滚
  • 一致性(Consistency):事务前后数据库状态保持一致
  • 隔离性(Isolation):并发事务间相互隔离
  • 持久性(Durability):事务提交后数据永久存储

二、Spring事务核心接口

java 复制代码
public interface PlatformTransactionManager {
    TransactionStatus getTransaction(TransactionDefinition definition);
    void commit(TransactionStatus status);
    void rollback(TransactionStatus status);
}

public interface TransactionDefinition {
    int getIsolationLevel();
    int getPropagationBehavior();
    int getTimeout();
    boolean isReadOnly();
}

三、事务配置方式

1. 声明式事务(推荐)

xml 复制代码
<!-- XML配置 -->
<tx:annotation-driven transaction-manager="txManager"/>

<bean id="txManager" 
      class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>
java 复制代码
// 注解驱动
@Configuration
@EnableTransactionManagement
public class AppConfig {
    @Bean
    public PlatformTransactionManager transactionManager(DataSource ds) {
        return new DataSourceTransactionManager(ds);
    }
}

2. 编程式事务

java 复制代码
transactionTemplate.execute(status -> {
    try {
        userDao.update(user1);
        logDao.insert(log);
        return true;
    } catch (Exception e) {
        status.setRollbackOnly();
        return false;
    }
});

四、@Transactional详解

属性配置

java 复制代码
@Transactional(
    propagation = Propagation.REQUIRED,
    isolation = Isolation.READ_COMMITTED,
    timeout = 30,
    readOnly = false,
    rollbackFor = {BusinessException.class},
    noRollbackFor = {SystemException.class}
)
public void businessMethod() { ... }

传播行为(Propagation)

行为类型 说明
REQUIRED(默认) 存在事务则加入,没有则新建
REQUIRES_NEW 总是新建事务,挂起当前事务
NESTED 嵌套事务,使用保存点实现部分回滚
SUPPORTS 存在事务则加入,没有则以非事务运行
NOT_SUPPORTED 非事务执行,挂起当前事务
MANDATORY 必须存在事务,否则抛异常
NEVER 必须非事务执行,否则抛异常

隔离级别(Isolation)

级别 脏读 不可重复读 幻读 说明
READ_UNCOMMITTED 最低隔离级别
READ_COMMITTED(默认) × 避免脏读
REPEATABLE_READ × × MySQL默认级别
SERIALIZABLE × × × 最高隔离级别

五、事务失效场景

  1. 非public方法:基于代理的AOP无法拦截private方法

  2. 自调用问题 :类内部方法调用不会经过代理对象
    解决方案

    java 复制代码
    @Autowired
    private ApplicationContext context;
    
    public void methodA() {
        context.getBean(ThisClass.class).methodB();
    }
  3. 异常类型不匹配:默认只回滚RuntimeException和Error

  4. 多线程调用:不同线程属于不同事务上下文

  5. 错误捕获异常 :catch后未重新抛出

    java 复制代码
    try { ... } 
    catch (Exception e) {
        // 需添加:throw new RuntimeException(e);
    }

六、高级特性

1. 事务同步

java 复制代码
TransactionSynchronizationManager.registerSynchronization(
    new TransactionSynchronization() {
        @Override
        public void afterCommit() {
            // 事务提交后操作
        }
    });

2. 多数据源事务

java 复制代码
@Bean
@Primary
public PlatformTransactionManager primaryTM(DataSource ds1) {
    return new DataSourceTransactionManager(ds1);
}

@Bean
public PlatformTransactionManager secondaryTM(DataSource ds2) {
    return new DataSourceTransactionManager(ds2);
}

// 使用指定事务管理器
@Transactional(transactionManager = "secondaryTM")
public void crossDatabaseOp() {...}

七、最佳实践

  1. 事务方法保持简短,避免远程调用
  2. 明确指定rollbackFor属性
  3. 只读查询添加@Transactional(readOnly=true)
  4. 嵌套事务使用PROPAGATION_NESTED
  5. 监控事务执行时间(超过3秒需优化)
相关推荐
鹿角片ljp1 小时前
LeetCode 64:最小路径和复盘|二维 DP 与 ACM 模式完整写法
java·数据结构·算法
泡海椒2 小时前
PDF 表格样式优化:jquick-pdf 边框、圆角、背景色
java·开发语言·pdf
景熙55234 小时前
15.Java 8 Stream 流入门到实战
java·开发语言·数据结构
wno7044 小时前
Spring Security权限控制
java·python·spring
杨运交5 小时前
[071][验证码模块]基于Spring拦截器的验证码认证设计思想
java·后端·spring
Geek-Chow5 小时前
CountDownLatch in Java
java
SL_staff5 小时前
从RBAC到场景化授权:《无忧·企业文档》三级权限模型的技术实践解析
java·开源·产品
传奇开心果编程6 小时前
【springboot基础语法学与练】第 1 课:从零开始
java·spring boot·后端·学习
SL_staff6 小时前
财务系统慎用低代码?从数据模型闭环看合规落地的技术实践
java·低代码·全栈