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

Spring事务原理的具体实现,以及包括源码以及具体在实际项目中的使用。

前言

  本篇文章将深入源码的取了解Spring事务以及在实际项目中的使用,Spring事务管理的基本机制,比如PlatformTransactionManager、声明式事务和编程式事务的区别,以及AOP在其中的作用。

  首先,我应该从Spring事务的核心接口开始,比如PlatformTransactionManager,以及它的实现类,比如DataSourceTransactionManager。然后解释事务的抽象过程,包括事务的创建、提交和回滚。接着需要讲声明式事务,基于@Transactional注解,以及背后的AOP代理机制,可能是JDK动态代理或者CGLIB。这部分需要提到Spring AOP如何拦截带有注解的方法,生成代理对象,然后在方法执行前后管理事务

  源码部分可能需要具体到AbstractPlatformTransactionManager,特别是getTransaction、commit、rollback这些方法。还有TransactionInterceptor,它在处理@Transactional时的逻辑,比如如何决定是否开启新事务,如何处理回滚规则。实际项目中,用户可能会遇到事务不生效的情况,比如自调用问题、异常未被捕获、数据库引擎不支持事务等,这些都需要提到。

  同时还要考虑到传播行为,比如REQUIRED和REQUIRES_NEW的区别,在源码里是如何处理的,可能涉及到TransactionStatus和保存点(savepoint)。实际应用中的例子,比如在Service层添加@Transactional,或者在需要的时候手动编程式事务管理。此外,事务的隔离级别和超时设置也是常见配置,需要结合源码中的处理方式。

  还想知道如何排查事务问题,比如日志配置,或者如何通过调试查看事务的状态。这时候可以建议开启Spring的调试日志,或者检查代理是否正确生成。另外,分布式事务可能是一个进阶话题,但用户的问题可能集中在单数据源的情况,所以可以简要提一下JTA,但重点放在本地事务上。

  Spring 事务管理是 Spring 框架中最重要的特性之一,其核心原理基于 AOP(面向切面编程) 和 事务抽象层。

一、Spring 事务的核心实现原理

  1. 事务抽象层(PlatformTransactionManager)
    Spring 通过 PlatformTransactionManager 接口抽象了事务管理,屏蔽了不同数据源(JDBC、JPA、JTA 等)的底层差异。核心方法:
  • getTransaction():开启事务(支持传播行为)
  • commit():提交事务
  • rollback():回滚事务

常见实现类:

  • DataSourceTransactionManager:基于 JDBC 的事务管理(单数据源)
  • JpaTransactionManager:JPA 事务管理
  • JtaTransactionManager:分布式事务管理(JTA)
  1. 事务的传播行为和隔离级别
    Spring 通过 TransactionDefinition 接口定义事务的传播行为(PROPAGATION_)和隔离级别(ISOLATION_),例如:

    • PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;否则新建事务
    • ISOLATION_READ_COMMITTED:读已提交隔离级别
  2. 声明式事务(@Transactional)
    通过 AOP 动态代理实现,基于 @Transactional 注解标记事务边界。代理对象会在方法执行前开启事务,执行后提交或回滚事务。

关键源码类:

  • TransactionInterceptor:拦截带有 @Transactional 注解的方法,处理事务逻辑。
  • AbstractPlatformTransactionManager:事务管理器基类,实现事务的提交和回滚逻辑

二、源码实现解析

  1. 事务的开启(getTransaction)
    源码入口:AbstractPlatformTransactionManager#getTransaction()
public final TransactionStatus getTransaction(TransactionDefinition definition) {
    // 1. 获取当前事务(如果存在)
    Object transaction = doGetTransaction();
    // 2. 处理传播行为(例如:REQUIRED、REQUIRES_NEW)
    if (isExistingTransaction(transaction)) {
        return handleExistingTransaction(definition, transaction, debugEnabled);
    }
    // 3. 开启新事务
    return startTransaction(definition, transaction, debugEnabled, suspendedResources);
}
  1. 事务提交与回滚

源码入口:TransactionInterceptor#invoke()

public Object invoke(MethodInvocation invocation) throws Throwable {
    // 1. 获取事务属性(@Transactional 配置)
    TransactionAttribute txAttr = determineTransactionAttribute(invocation.getMethod());
    // 2. 开启事务
    TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
    try {
        // 3. 执行目标方法
        Object retVal = invocation.proceed();
        // 4. 提交事务
        commitTransactionAfterReturning(txInfo);
        return retVal;
    } catch (Throwable ex) {
        // 5. 回滚事务(根据异常类型判断)
        completeTransactionAfterThrowing(txInfo, ex);
        throw ex;
    }
}
  1. 回滚条件判断
    源码入口:RuleBasedTransactionAttribute#rollbackOn()
public boolean rollbackOn(Throwable ex) {
    // 检查是否匹配回滚规则(默认对 RuntimeException 和 Error 回滚)
    for (RollbackRuleAttribute rule : rollbackRules) {
        if (rule.getDepth(ex) >= 0) {
            return true;
        }
    }
    return false;
}

三、实际项目中的应用

  1. 声明式事务配置
    在 Service 层使用 @Transactional 注解:
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
    public void createUser(User user) {
        userRepository.save(user);
        // 其他数据库操作(自动加入同一事务)
    }
}
  1. 编程式事务管理
    手动控制事务边界(适用于复杂逻辑):
@Service
public class OrderService {
    @Autowired
    private PlatformTransactionManager transactionManager;

    public void placeOrder(Order order) {
        TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
        try {
            // 业务逻辑
            transactionManager.commit(status);
        } catch (Exception ex) {
            transactionManager.rollback(status);
            throw ex;
        }
    }
}
  1. 多数据源事务管理
    在 Spring Boot 中配置多个 DataSource 和 TransactionManager:

    # application.yml
    spring:
      datasource:
        primary:
          url: jdbc:mysql://localhost/db1
        secondary:
          url: jdbc:mysql://localhost/db2
    
@Configuration
public class DataSourceConfig {
    @Bean
    @Primary
    @ConfigurationProperties("spring.datasource.primary")
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties("spring.datasource.secondary")
    public DataSource secondaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @Primary
    public PlatformTransactionManager primaryTxManager(DataSource primaryDataSource) {
        return new DataSourceTransactionManager(primaryDataSource);
    }

    @Bean
    public PlatformTransactionManager secondaryTxManager(@Qualifier("secondaryDataSource") DataSource secondaryDataSource) {
        return new DataSourceTransactionManager(secondaryDataSource);
    }
}

四、常见问题与解决方案

  1. 事务不生效的常见原因

    • 自调用问题:同类方法内部调用 @Transactional 方法(需通过代理对象调用)。
    • 异常被捕获:未将异常抛出到事务拦截器。
    • 数据库引擎不支持事务(如 MySQL 的 MyISAM)。
  2. 调试事务问题

    • 开启 Spring 事务日志:
    logging.level.org.springframework.transaction=DEBUG
    logging.level.org.springframework.jdbc=DEBUG
    
  3. 分布式事务
    对于跨数据源或微服务场景,可结合 Seata 或 JTA 实现分布式事务。

五、总结

  Spring 事务的核心是通过 AOP 动态代理和 PlatformTransactionManager 实现事务的抽象化管理。理解源码逻辑(如 TransactionInterceptor 和传播行为处理)有助于解决实际项目中的事务问题。实际应用中需注意事务的传播行为、隔离级别和异常回滚规则。

相关文章:

  • 【etcd】etcd_APIs 简单KV、watch、lease、txn命令
  • 数据结构-顺序表
  • 东方财富股吧发帖与评论爬虫
  • 基于腾讯云TI-ONE 训练平台快速部署和体验 DeepSeek 系列模型
  • 「AI学习笔记」机器学习与深度学习的区别:从技术到产品的深度解析(四)...
  • 如何高效利用 AI 工具提升开发效率?
  • 机器学习PCA和LDA
  • du-磁盘占用管理
  • 基于Python实现的缓存淘汰替换策略算法,该算法将缓存分区
  • MongoDB 架构设计:深入解析核心组件与工作原理
  • 二分搜索法、二分查找法【C/C ++】
  • 数据结构:最小生成树
  • FFmpeg源码:av_strlcpy函数分析
  • 探索 DeepSeek:AI 领域的璀璨新星
  • 深度学习实战道路裂缝缺陷识别
  • 计算四个锚点TOA定位中GDOP的详细步骤和MATLAB例程
  • PyTorch 源码学习:阅读经验 代码结构
  • Flink提交pyflink任务
  • pytest asyncio 支持插件 pytest-asyncio
  • 基于51单片机的的鸡笼补光和恒温系统的设计与实现(源程序+Protues仿真+电路图+元件清单+器件手册)
  • 昂立教育:去年减亏1.39亿元,今年以“利润持续增长”为核心目标
  • 新一届中国女排亮相,奥运冠军龚翔宇担任队长
  • 张译、惠英红分获第二十届中国电影华表奖优秀男、女演员奖
  • 视频丨伊朗阿巴斯港一处油罐发生高强度爆炸:造成大面积破坏,伤亡不明
  • 李家超称香港将部署为内地企业提供供应链服务,突破美国封锁
  • 从息屏24小时到息屏1小时,姚明在深圳开启落地试点