事务处理是数据库访问层非常重要的一项操作,那么Spring给我们提供的事务是一个什么样的事务呢?
Spring 声明式事务处理
概念
程序员不再负责处理事务,事务处理交给Spring容器来做。程序员做的是声明。那么声明什么呢?
具体声明:
程序员负责的两个内容:
- 对表的CRUD操作:目标类的目标方法
- 告诉Spring容器什么样的目标方法采用什么样的事务策略来处理。
Spring 容器负责(切面):事务的处理
Spring采用的实现原理:采用AOP技术来实现的。
Spring 事务的架构
分析Spring的事务的架构我们从他的几个事务的管理的几个类源码中看吧:
下面直接放代码了!
PlatformTransactionManager类部分源码
|
|
AbstractPlatformTransactionManager类部分源码:
DataSourceTransactionManager类源码 不在tx事务包中,而是在JDBC的包中。
HibernateTransactionManager类源码,在orm包下
通过观察源代码的分析,Spring的事务的整体架构 如下图:
从图中可以知道,HibernateTransactionManager和DataSourceTransactionManager都是继承于AbstractPlatformTransactionManager,而AbstractPlatformTransactionManager实现了PlatformTransactionManager接口,其中AbstractPlatformTransactionManager是一个抽象类, 实现了一部分的方法,还有一些方法是抽象的,那么这样的目的是在于干什么呢?
目的是在于: 面向接口编程,
那么Spring他就怎么面向接口编程的了?
所以根据上面的分析的Spring的事务架构,可以知道,只要我们遵循Spring中的那套事务规范,并且实现了,那么Spring内部就可以按照我们的要求处理数据库,而不管是处理什么数据,不管不同数据库操作方式的不同,只要准许这个架构,那么就可以集成到Spring中去,Spring内部准备可一个壳子,只要你往里面填东西,人家Spring就可以帮你干活了。
再来看AbstractPlatformTransactionManager抽象类不管是它的作用还是一任何一个Java的抽象,抽象类的作用是: 将公共的方法实现了,然后不同的方法就声明为抽象,那么谁继承,那谁就实现。
所以,AbstractPlatfromTransactionManager, 为什么获取事务被整成抽象的方法? 因为不同的数据库技术,获取数据库事务是不同的, 比如说JDBC是通过一个方法connection.setAutoCommit(flase),获取事务,为隐式操作,事务和数据库链接是非常紧密的。
事务的定义
在顶层的PlatformTransactionManager类中我们发现有一个TransactionDefinition类,那么这个类是什么呢?里面有什么呢?先来看下面的源码吧!
TransactionDefinition 类部分源码:
从类名可以知道,这个类是Spring用来描述事务的。其中这个类主要的有两个功能是:
- 描述事务的传播机制
- 描述事务的隔离机制
那么什么叫传播机制? 主要用于解决什么问题的呢?我们先来看下面的一种情况:
假设有一个Service层中有一个AService类,里面有一个aService方法,它调用了Dao层BDao和CDao类中的bDao和cDao方法,那么如果bDao和cDao在处理的时候分别存在事务,我们在aService方法中,本身也是存在一个事务的,那么加入该方法里面的bDao和cDao中的事务怎么处理呢?
|
|
那么在aService中共有多少个事务?很显然,有三个事务,这个是不允许的呀,一个方法中有三个事务。那么怎么解决呢?这个问题是属于事务嵌套的问题,那么Spring中的事务传播机是用来解决事务的嵌套问题。Spring中有如下几种传播机制:
一般情况下我们选择的是第一个。
那么是隔离机制是为了数据的规范性的约束机制了,它和数据的隔离机制很相似,那么我们来看一下几种事务的隔离级别:
下面是Spring的隔离机制:
隔离机制越高,效率越低,数据规范性越强,隔离机制越低,效率越高,数据就越烂(可能读取脏数据等)。
说明:通过Spring的事务处理架构,再通过配置文件,配置具体的实现事务的类,就可以让Spring容器知道是什么样的技术来操作数据库,通过对事务状态的判断,通过事务的定义,就让Spring可以知道具体的目标方法采用什么样的事务策略来处理了。