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秒需优化)
相关推荐
珹洺2 分钟前
Java-Spring入门指南(五)Spring自动装配
android·java·spring
帧栈9 分钟前
并发编程原理与实战(二十七)深入剖析synchronized底层基石ObjectMonitor与对象头Mark Word
java
imHanweihu13 分钟前
基于POI-TL实现动态Word模板数据填充(含图表):从需求到落地的完整开发实践
java·onlyoffice·poi-tl
月夕·花晨16 分钟前
Gateway -网关
java·服务器·分布式·后端·spring cloud·微服务·gateway
失散1317 分钟前
分布式专题——6 Redis缓存设计与性能优化
java·redis·分布式·缓存·架构
杏花春雨江南17 分钟前
Spring Cloud Gateway 作为一个独立的服务进行部署吗
java·开发语言
GSDjisidi18 分钟前
东京本社招聘 | 财务负责人 & 多个日本IT岗位(Java/C++/Python/AWS 等),IT营业同步招募
java·开发语言·aws
叫我阿柒啊29 分钟前
Java全栈开发面试实战:从基础到微服务的完整技术栈解析
java·spring boot·微服务·前端框架·vue·jwt·全栈开发
前行的小黑炭30 分钟前
Android:在项目当中可能会遇到的ANR,应该如何解决?
android·java·kotlin