Spring Transaction
- 不使用Spring,如何实现事务
- Spring Transaction
- 小结
不使用Spring,如何实现事务
public Object doTransaction() {
// 开启事务
connection.beginTransaction();
try {
// 执行事务
Object result = process();
// 提交事务
connection.commit();
return result;
} catch(Exception e) {
// 发生异常时回滚
connection.rollback();
throw e;
}
}
这是一个Java简单实现的事务的伪代码,逻辑非常简单,首先开启事务,然后执行事务,如果发生异常则执行回滚,否则提交事务。
下面,我们看一下Spring是如何实现一个简单事务的。
Spring Transaction
Spring 将事务处理过程拆分了几个不同的角色,每个角包都有各自的职责(面向对象设计),下图为一个简单事务模型。
TransactionDefinition——事务定义,描述一个事务(如超时时间、隔离级别等),不同的描述会决定事务不同的执行流程,类似配置文件功能。
TransactionOperation——事务操作,封装要确保原子性的代码逻辑,传入一个函数表达式即可。
事务模板(TransactionTemplate),从名字可以看出这是一个模板方法类,通过这个类我们可以设置事务属性,并调用execute方法,模板方法如下,
public <T> T execute(TransactionCallback<T> action) throws TransactionException {
assert transactionManager != null;
beginTransaction();
try {
// 执行业务逻辑
action.doInTransaction();
} catch (Exception e) {
transactionManager.rollback();
throw e;
}
transactionManager.commit();
}
代码结构和开篇例子是基本一致的。区别就是,Spring可以通过对TransactionTemplate进行简单的配置就可以完成整个事务处理,比后者在代码可维护性、逻辑清晰程度上都有优势。
所以,通过上述2个角色对事务进行抽象,Spring只需要完成以下3个步骤就可以实现一个事务,
- new 一个TransactionTemplate实例,传递一个TransactionManager实例进去;
- 定义事务属性
- 传入执行逻辑
// 1,new 一个TransactionTemplate实例,传递一个TransactionManager实例进去
PlatformTransactionManager manager = new DataSourceTransactionManager(datasource);
TransactionTemplate template = new TransactionTemplate(dataSourceTransactionManager);
// 2,定义事务属性
template.setIsolationLevel(...);
template.setTimeout(...);
template.execute(new TransactionCallback<Object>(){
Object doInTransaction(TransactionStatus status) {
// 3,传入执行逻辑
... ...
}
});
上面代码中,模板方法TransactionTemplate执行时候会获取TransactionDefinition定义中事务配置信息,调用TransactionOperation执行具体的事务逻辑。
另外,注意到上面伪代码中有一个PlatformTransactionManager的类,它是一个事务管理器,负责具体事务的执行,如commit(),rollback()等关键操作,是最终干活的一个类。
- 通过TransactionDefinition开启一个事务,返回TransactionStatus
- TransactionStatus是一个有状态对象,负责当前事务的回滚或提交
这就是一个事务管理器的基本定义,无论是单机事务管理还是分布式事务管理都可以用上面接口描述,场景也并非只限制于数据库。所以,希望当我们遇到非数据库场景的事务需求时,能够快速想起这个事务框架,快速优雅地实现多场景事务处理。
TansactionManager作为Spring事务中的第3个角色,也是最重要的一个角色,为了避免过多延伸,我们这里暂不作介绍。
小结
以上只是Spring事务框架的一部分,优势只体现在代码可维护性与易用性上。所以,可能大家觉得开篇代码也并没有多差,除了代码比较冗余外,使用起来可能还会更简单,那为什么还要学习Spring的框架呢?
但凡一个牛的框架它一定是解决了之前不能解决的问题,否则就不可能被广泛地使用,下一章节我来分析事务的传播性。