Small-Spring项目中的事务管理实现解析
一、事务管理基础概念
在数据库操作中,事务(Transaction)是一组不可分割的操作序列,这些操作要么全部执行成功,要么全部不执行。Spring框架提供了强大而灵活的事务管理机制,small-spring项目也实现了类似的功能。
1.1 Spring事务管理方式
Spring支持两种主要的事务管理方式:
-
声明式事务:基于AOP实现,通过配置或注解方式管理事务
- 在方法执行前后进行拦截
- 根据配置自动创建/加入事务
- 根据执行结果自动提交或回滚
- 与业务代码解耦,使用简便
-
编程式事务:通过编码方式实现事务控制
- 类似传统JDBC事务管理
- 使用TransactionTemplate或PlatformTransactionManager
- 灵活性高但代码侵入性强
small-spring项目主要实现了声明式事务的功能,这也是Spring中最常用的方式。
二、事务管理核心实现原理
2.1 事务管理核心组件
small-spring的事务管理实现涉及多个核心组件,它们协同工作完成事务控制:
-
事务定义(TransactionDefinition)
- 定义事务的基本属性:传播行为、隔离级别、超时时间等
- 对应接口:
TransactionDefinition
- 默认实现:
DefaultTransactionDefinition
-
事务属性(TransactionAttribute)
- 扩展事务定义,增加回滚规则判断
- 核心方法:
rollbackOn(Throwable ex)
- 实现类:
DefaultTransactionAttribute
和RuleBasedTransactionAttribute
-
事务注解解析(TransactionAnnotationParser)
- 解析
@Transactional
注解 - 将注解属性转换为事务定义
- 实现类:
SpringTransactionAnnotationParser
- 解析
-
事务管理器(PlatformTransactionManager)
- 事务操作的核心接口
- 主要方法:获取事务、提交、回滚
- 抽象实现:
AbstractPlatformTransactionManager
2.2 事务执行流程
small-spring的事务执行遵循以下典型流程:
-
解析事务属性
- 通过
AnnotationTransactionAttributeSource
解析方法或类上的@Transactional
注解 - 将注解属性转换为
TransactionAttribute
对象
- 通过
-
创建事务
- 通过
PlatformTransactionManager
根据事务定义创建事务 - 返回
TransactionStatus
表示当前事务状态
- 通过
-
执行业务逻辑
- 在事务上下文中执行目标方法
- 捕获方法执行过程中的异常
-
提交或回滚
- 根据执行结果和异常类型决定提交或回滚
- 通过
TransactionStatus
完成最终操作
三、关键实现细节分析
3.1 事务属性解析
AnnotationTransactionAttributeSource
是解析事务注解的核心类,它通过以下步骤完成解析:
- 检查方法或类上是否存在
@Transactional
注解 - 使用
SpringTransactionAnnotationParser
解析注解属性 - 将注解属性转换为
RuleBasedTransactionAttribute
对象 - 设置传播行为、隔离级别、超时等属性
- 配置回滚规则(rollbackFor/noRollbackFor)
3.2 事务管理器实现
AbstractPlatformTransactionManager
是事务管理器的抽象实现,定义了事务处理的基本流程:
-
获取事务
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); }
-
提交事务
public final void commit(TransactionStatus status) { // 1. 检查事务状态 if (status.isCompleted()) { throw new IllegalTransactionStateException(...); } // 2. 执行提交 if (status.isNewTransaction()) { doCommit(status); } }
-
回滚事务
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事务的核心原理:
- 通过AOP拦截实现声明式事务
- 使用注解配置事务属性
- 抽象事务管理器处理不同数据源
- 完善的异常处理和回滚机制
理解这些实现细节有助于我们更好地使用Spring事务,也能在遇到事务相关问题时快速定位原因。small-spring的简洁实现是学习Spring事务原理的优秀范例。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考