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秒需优化)
相关推荐
q***33372 小时前
oracle 12c查看执行过的sql及当前正在执行的sql
java·sql·oracle
Y***h1875 小时前
第二章 Spring中的Bean
java·后端·spring
8***29315 小时前
解决 Tomcat 跨域问题 - Tomcat 配置静态文件和 Java Web 服务(Spring MVC Springboot)同时允许跨域
java·前端·spring
CoderYanger5 小时前
优选算法-栈:67.基本计算器Ⅱ
java·开发语言·算法·leetcode·职场和发展·1024程序员节
q***06296 小时前
Tomcat的升级
java·tomcat
多多*6 小时前
Java复习 操作系统原理 计算机网络相关 2025年11月23日
java·开发语言·网络·算法·spring·microsoft·maven
青云交6 小时前
Java 大视界 -- Java 大数据在智能物流无人配送车路径规划与协同调度中的应用
java·spark·路径规划·大数据分析·智能物流·无人配送车·协同调度
d***81726 小时前
解决SpringBoot项目启动错误:找不到或无法加载主类
java·spring boot·后端
ᐇ9596 小时前
Java集合框架深度实战:构建智能教育管理与娱乐系统
java·开发语言·娱乐
K***72846 小时前
开源模型应用落地-工具使用篇-Spring AI-Function Call(八)
人工智能·spring·开源