相信 Java 程序员一定听过大名鼎鼎的 Spring 框架,Spring 框架的低侵入性,开奖,模块间的解耦,DI 机制,AOP 特性等为程序员大大降低了程序开发的难度,可以说 Spring 目前是最流行的框架技术,占有很大一部分市场,为广大程序员带来巨大的便利。 今天来聊一聊 Spring 中的事务管理为我们做了些什么事。 由于 DI 和 AOP 是整个 Spring 框架的灵魂,而且今天要讲的事务管理也是基于 AOP 的,所以不明白的请先移步至:
先看一段老代码: 上面代码是一个完整事务,缺点很明显,就是比较啰嗦。实际上要做的事情只有向数据库中插入一条数据。如果每组 jdbc 操作都要去控制 connection,preparedStatement 的状态,一堆的 try-catch-finally 代码,看起来很头疼,而且非常容易写错,忘记关闭 connection 也会导致资源耗尽这样致命的错误。 程序员都是很懒的,这些复杂的重复率非常高的代码最好能交给某个模版去帮忙管理,用技术干掉重复的事情,从而能更好的专注于自己的业务代码。 下面介绍一下 Spring 怎样去帮助我们管理了上面这些状态,先看一下 Spring 中声明式事务能简化到怎样的程度。 1、需要配置 dataSource, transactionManager, sqlSessionFactory, MapperScannerConfigurer 2、业务逻辑中事务的入口 看上去使用 Spring 帮我们管理的事务是非常简单的,而且业务代码简洁到了极致。 只要我们配置好了相应的 dataSource,transactionManager, sqlSessionFactory, MapperScannerConfigurer, 在需要事务的方法上加上注解 @Transactional 即可。 @Transactional 这个注解里面有几个属性用来描述程序员需要的事务类型。 看一下源码里面有如下几个属性: 那么 Spring 框架是怎样做到的呢? @Transactional 这个注解的背后有怎样的逻辑呢? 为什么那些复杂的状态控制代码,资源释放的代码都看不到了呢? 将一组 jdbc 操作放入同一个事务需要的几个步骤: 开启事务 jdbc 操作 成功:提交事务 异常:回滚事务 释放资源 实际上,正是 Spring 帮助我们做了上述1,3,4三步(第2步使我们的业务代码)。看一下之前配置的 transactionManager 以及其父类AbstractPlatformTransactionManager,AbstractPlatformTransactionManager继承了接口 PlatformTransactionManager,而该接口中只有三个方法: 可以看出这三个方法分别对应了1)3)两个步骤。 继续看抽象类 AbstractPlatformTransactionManager 中的方法,AbstractPlatformTransactionManager 的方法有很多,其中有几个方法值得注意: 看到这里1)3)4)三步都有了方法对应。每个 public 方法又对应了以“do*”开头各自 protected abstract 方法,这是什么意思呢? 实际上继承于AbstractPlatformTransactionManager 的类有很多,如DataSourceTransactionManager , JtaTransactionManager, HibernateTransactionManager 等,不管是哪一个种,总要有 getTransaction,commit,rollback的方法,所以这个三个方法在接口中,不过具体实现方式有所区别,所以具体的实现需要而且是必须在子类中完成。 AbstractPlatformTransactionManager 规定了这三个方法的调用顺序,真正的细节在子类中以”do*”开头的方法中实现,这也正是大多数抽象类的作用所在。 当然 AbstractPlatformTransactionManager 中还有很多其它方法,我们这里只关注最重要的几个主干上方法,也就是接口中规定的方法以及其子类中的实现,这里子类选取 DataSourceTransactionManager 进行代码分析。 首先先结合时序图看一下几个主要方法的调用: 下面与源码相结合,先看一下入口处,也就是 AbstractPlatformTransactionManager 中 getTransaction(TransactionStatus status) 方法: 跳转到子类 doBegin(…) 方法中: (责任编辑:本港台直播) |