Small-Spring项目中的事务管理实现解析

Small-Spring项目中的事务管理实现解析

small-spring 🌱《 Spring 手撸专栏》,本专栏以 Spring 源码学习为目的,通过手写简化版 Spring 框架,了解 Spring 核心原理。在手写的过程中会简化 Spring 源码,摘取整体框架中的核心逻辑,简化代码实现过程,保留核心功能,例如:IOC、AOP、Bean生命周期、上下文、作用域、资源处理等内容实现。 small-spring 项目地址: https://gitcode.com/gh_mirrors/smal/small-spring

一、事务管理基础概念

在数据库操作中,事务(Transaction)是一组不可分割的操作序列,这些操作要么全部执行成功,要么全部不执行。Spring框架提供了强大而灵活的事务管理机制,small-spring项目也实现了类似的功能。

1.1 Spring事务管理方式

Spring支持两种主要的事务管理方式:

  1. 声明式事务:基于AOP实现,通过配置或注解方式管理事务

    • 在方法执行前后进行拦截
    • 根据配置自动创建/加入事务
    • 根据执行结果自动提交或回滚
    • 与业务代码解耦,使用简便
  2. 编程式事务:通过编码方式实现事务控制

    • 类似传统JDBC事务管理
    • 使用TransactionTemplate或PlatformTransactionManager
    • 灵活性高但代码侵入性强

small-spring项目主要实现了声明式事务的功能,这也是Spring中最常用的方式。

二、事务管理核心实现原理

2.1 事务管理核心组件

small-spring的事务管理实现涉及多个核心组件,它们协同工作完成事务控制:

  1. 事务定义(TransactionDefinition)

    • 定义事务的基本属性:传播行为、隔离级别、超时时间等
    • 对应接口:TransactionDefinition
    • 默认实现:DefaultTransactionDefinition
  2. 事务属性(TransactionAttribute)

    • 扩展事务定义,增加回滚规则判断
    • 核心方法:rollbackOn(Throwable ex)
    • 实现类:DefaultTransactionAttributeRuleBasedTransactionAttribute
  3. 事务注解解析(TransactionAnnotationParser)

    • 解析@Transactional注解
    • 将注解属性转换为事务定义
    • 实现类:SpringTransactionAnnotationParser
  4. 事务管理器(PlatformTransactionManager)

    • 事务操作的核心接口
    • 主要方法:获取事务、提交、回滚
    • 抽象实现:AbstractPlatformTransactionManager

2.2 事务执行流程

small-spring的事务执行遵循以下典型流程:

  1. 解析事务属性

    • 通过AnnotationTransactionAttributeSource解析方法或类上的@Transactional注解
    • 将注解属性转换为TransactionAttribute对象
  2. 创建事务

    • 通过PlatformTransactionManager根据事务定义创建事务
    • 返回TransactionStatus表示当前事务状态
  3. 执行业务逻辑

    • 在事务上下文中执行目标方法
    • 捕获方法执行过程中的异常
  4. 提交或回滚

    • 根据执行结果和异常类型决定提交或回滚
    • 通过TransactionStatus完成最终操作

三、关键实现细节分析

3.1 事务属性解析

AnnotationTransactionAttributeSource是解析事务注解的核心类,它通过以下步骤完成解析:

  1. 检查方法或类上是否存在@Transactional注解
  2. 使用SpringTransactionAnnotationParser解析注解属性
  3. 将注解属性转换为RuleBasedTransactionAttribute对象
  4. 设置传播行为、隔离级别、超时等属性
  5. 配置回滚规则(rollbackFor/noRollbackFor)

3.2 事务管理器实现

AbstractPlatformTransactionManager是事务管理器的抽象实现,定义了事务处理的基本流程:

  1. 获取事务

    public final TransactionStatus getTransaction(TransactionDefinition definition) {
        // 1. 获取当前事务对象
        Object transaction = doGetTransaction();
    
        // 2. 根据传播行为处理事务
        if (isExistingTransaction(transaction)) {
            // 处理已存在事务的情况
            return handleExistingTransaction(definition, transaction);
        }
    
        // 3. 创建新事务
        doBegin(transaction, definition);
        return prepareTransactionStatus(definition, transaction, true, false);
    }
    
  2. 提交事务

    public final void commit(TransactionStatus status) {
        // 1. 检查事务状态
        if (status.isCompleted()) {
            throw new IllegalTransactionStateException(...);
        }
    
        // 2. 执行提交
        if (status.isNewTransaction()) {
            doCommit(status);
        }
    }
    
  3. 回滚事务

    public final void rollback(TransactionStatus status) {
        // 1. 检查事务状态
        if (status.isCompleted()) {
            throw new IllegalTransactionStateException(...);
        }
    
        // 2. 执行回滚
        if (status.isNewTransaction()) {
            doRollback(status);
        }
    }
    

3.3 AOP事务拦截

TransactionInterceptor是事务AOP拦截的核心类,主要逻辑在invokeWithinTransaction方法中:

protected Object invokeWithinTransaction(Method method, Class<?> targetClass,
    final InvocationCallback invocation) throws Throwable {
    
    // 1. 获取事务属性
    TransactionAttribute txAttr = getTransactionAttributeSource()
        .getTransactionAttribute(method, targetClass);
    
    // 2. 获取事务管理器
    PlatformTransactionManager tm = determineTransactionManager(txAttr);
    
    // 3. 创建事务
    TransactionStatus status = tm.getTransaction(txAttr);
    
    try {
        // 4. 执行业务方法
        Object retVal = invocation.proceedWithInvocation();
        
        // 5. 提交事务
        tm.commit(status);
        return retVal;
    } catch (Throwable ex) {
        // 6. 异常处理
        completeTransactionAfterThrowing(txAttr, status, ex);
        throw ex;
    }
}

四、使用示例

下面是一个使用small-spring事务管理的完整示例:

// 1. 定义服务接口
public interface JdbcService {
    void saveData(JdbcTemplate jdbcTemplate);
}

// 2. 实现服务类并添加事务注解
@Transactional(rollbackFor = Exception.class)
public class JdbcServiceImpl implements JdbcService {
    @Override
    public void saveData(JdbcTemplate jdbcTemplate) {
        jdbcTemplate.execute("insert into teacher(teacher_name) values ('李老师')");
        jdbcTemplate.execute("insert into user(id,username) values(1,'重复数据')");
    }
}

// 3. 测试代码
@Test
public void testTransaction() {
    // 创建数据源和JdbcTemplate
    DruidDataSource dataSource = new DruidDataSource();
    dataSource.setUrl("jdbc:mysql://localhost:3306/test");
    dataSource.setUsername("root");
    dataSource.setPassword("123456");
    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
    
    // 创建服务实例
    JdbcService jdbcService = new JdbcServiceImpl();
    
    // 配置事务相关组件
    AnnotationTransactionAttributeSource attributeSource = 
        new AnnotationTransactionAttributeSource();
    DataSourceTransactionManager transactionManager = 
        new DataSourceTransactionManager(dataSource);
    TransactionInterceptor interceptor = 
        new TransactionInterceptor(transactionManager, attributeSource);
    
    // 创建AOP代理
    AdvisedSupport advisedSupport = new AdvisedSupport();
    advisedSupport.setTargetSource(new TargetSource(jdbcService));
    advisedSupport.setMethodInterceptor(interceptor);
    
    // 获取代理对象并调用
    JdbcService proxy = (JdbcService) new Cglib2AopProxy(advisedSupport).getProxy();
    proxy.saveData(jdbcTemplate);
}

当执行上述测试时,第二条SQL语句会因主键冲突抛出异常,整个事务会回滚,第一条插入操作也不会生效。

五、总结

small-spring项目的事务管理实现展示了Spring事务的核心原理:

  1. 通过AOP拦截实现声明式事务
  2. 使用注解配置事务属性
  3. 抽象事务管理器处理不同数据源
  4. 完善的异常处理和回滚机制

理解这些实现细节有助于我们更好地使用Spring事务,也能在遇到事务相关问题时快速定位原因。small-spring的简洁实现是学习Spring事务原理的优秀范例。

small-spring 🌱《 Spring 手撸专栏》,本专栏以 Spring 源码学习为目的,通过手写简化版 Spring 框架,了解 Spring 核心原理。在手写的过程中会简化 Spring 源码,摘取整体框架中的核心逻辑,简化代码实现过程,保留核心功能,例如:IOC、AOP、Bean生命周期、上下文、作用域、资源处理等内容实现。 small-spring 项目地址: https://gitcode.com/gh_mirrors/smal/small-spring

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

符汝姿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值