12.4 事务相关资源
你现在应该知道如何创建不同的事务管理器,还有他们怎么和相关的资源关联起来,这些资源需要和事务进行某种同步(比如讲 DataSourceTransactionManager
和JDBC DataSource
关联, HibernateTransactionManager
和 Hibernate SessionFactory
,关联). 这一小段描述程序代码怎么直接或者间接使用持久层api(JDBC, Hibernate, JDO),让这些资源被创建,复用,还有适当的回收资源。还要讨论事务同步,通过 PlatformTransactionManager
,如何被触发,
12.4.1 较高层的同步资源
推荐的方法是使用spring的基于持久层整合的jdbc template,或者使用一些ORM本地API,这些API里面有:可以关联事务的工厂bean或者有管理本地资源的工厂的代理。这些可以关联事务特性的解决方案自己内部就处理了资源的创建,复用和回收清理,附带有资源的事务同步功能,还有异常映射. 因此用户的数据访问代码不需要做这种事情,只需要关注业务逻辑,而不是简单重复的事务管理代码。通常,如果你使用ORM的本地API或者使用 JdbcTemplate
来访问数据库,随后的章节会详细叙述解决方案。
12.4.2 较底层的同步资源
如 DataSourceUtils
(JDBC), EntityManagerFactoryUtils
(JPA), SessionFactoryUtils
(Hibernate),PersistenceManagerFactoryUtils
(JDO), 这一类的class位于较底层。.如果你要程序代码直接处理本地的持久api,你需要使用这些类,来保证spring框架获得能够被spring管理的连接实例。这样事务可以被同步,中间发生的异常也可以被合理的映射到一个统一的异常处理API上。
拿JDBC做个例子,本来的做法是调用 DataSource
上的 getConnection()
来获得连接,这里你需要通过Spring的org.springframework.jdbc.datasource.DataSourceUtils
类来做这件事情:
Connection conn = DataSourceUtils.getConnection(dataSource);
如果事务已经有一个连接相关联了,这个连接实例会被返回。否则,这个方法会创建一个新的连接实例,和这个已有的事务相关联,这样在同样的事务边界里可以复用同样的连接。 上面还提过, 任何SQLException
都被封装在Spring的 CannotGetJdbcConnectionException
, 这是spring的unchecked异常体系DataAccessExceptions里面的一个异常。这样比使用 SQLException
能够拿到更多的异常信息,也增加数据库,或者不同持久化技术的移植性。
这种方法没有spring事务管理也一样有用,事务管理特性是可选的,无论你是不是使用spring事务管理,你都可以这么用。
当然,一旦你使用spring的jdbc,jpa,hibernate支持,你一般会倾向不去使用 DataSourceUtils
或者其他helper类,因为你使用spring数据层抽象,比直接使用这些底层api更爽。比如将,如果你使用springJdbcTemplate
or jdbc.object
包,能简化jdbc使用,能够正确的获取连接,spring在背后为你做了事情,你不需要写任何特殊的代码
12.4.3 TransactionAwareDataSourceProxy
在最底层有我们的 TransactionAwareDataSourceProxy
类. 这是一个为 DataSource
的代理类。他封装了目标 DataSource
,增加了整合spring事务管理的能力。从这个角度讲,他和Java EE服务器提供的,事务管理的JNDI DataSource
非常类似。
你几乎没有必要直接使用这个类,除了你的代码必须使用一个标准的JDBC DataSource
接口实现. 如果是这样,很可能这段代码可用,但是侵入到spring的事务管理,更推荐写一段新的代码使用上面提过的spring高层次数据接口抽象。