spring的事务管理的一些看法

来源:互联网 发布:小米6数据断流 编辑:程序博客网 时间:2024/06/05 08:27

以下内容转贴于IBM DEVELOPLER的《Spring 事务管理高级应用难点剖析》系列

 

虽然使用基本的JDBC进行开发的时候是处于DAO层的,但事务管理在流程上来说是属于业务层的内容,因此在spring中如果无论使用声明式还是编程式的事务管理,都是在service层进行封装的。这个时候就会出现一个问题,实际与数据库交互的时候是在DAO层进行的,但事务的开始是在service层方法运行之前,因此必须保证在DAO层不自行写上DataSource.getConnection等代码,因为这样的话在进行数据库交互时使用的连接与事务开启时不为同一个,为解决这个问题,spring为我们准备了DataSourceUtils,调用其getConnection方法所返回的connection是根据上下文事务而来,简单来说,如果事务管理器中已有一个打开的connection,则直接返回该对象,否则才会新建一个对象,当然DataSourceUtils是只对于DataSource进行了封装的,如果使用其它的数据库操作方式如Hibernate等则有另外对应的类,如下表:
Spring JDBC  org.springframework.jdbc.datasource.DataSourceUtils 
Hibernate  org.springframework.orm.hibernate3.SessionFactoryUtils 
iBatis  org.springframework.jdbc.datasource.DataSourceUtils 
JPA  org.springframework.orm.jpa.EntityManagerFactoryUtils 
JDO  org.springframework.orm.jdo.PersistenceManagerFactoryUtils
又或者我们只要使用如JdbcTemplate等模板类来处理数据库的操作则可更节省开发的人力,有些人可能会有疑问,如果在service层已经开始一个事务,在dao层再使用模板来进行数据库交互是否会出现我们之前所说的新打开一个连接的情况呢?很荣幸的告诉你,不一定会,通过了解模板类的实现,可以看到在模板类里面连接也是调用了DataSourceUtils等工具类而来的,因此其实spring工具类也处理了事务相关的内容,不单单只是获取连接及关闭连接,而说不一定主要是还要看该事务的传播属性如何。
从上面的说明中可以了解到使用spring提供的类了操作事务其实已经完全可以满足我们的需求啦,但如果你依然希望通过DataSource.getConnection等来获取连接,spring依然为我们提供了相应的类,以DataSource为例的话具体类为TransactionAwareDataSourceProxy,如类名所示,该类起到对原DataSource封装的目的,我们可在配置文件中按如下配置

在需要DataSource的地方使用上封装了代理的类,这样即使你直接调用其getConnection也不是直接返回一个新的连接,其后台处理也是DataSourceUtils一样,会处理事务内容。其它类如下表:
Spring JDBC  org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy 
Hibernate  org.springframework.orm.hibernate3.LocalSessionFactoryBean 
iBatis  org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy 
JPA  无 
JDO  org.springframework.orm.jdo.TransactionAwarePersistenceManagerFactoryProxy