24
25 //③最后再使用DataSourceUtils释放数据连接
26 DataSourceUtils.releaseConnection(con, getDataSource());
27 }
28 }
在①处通过DataSourceUtils.getConnection()获取连接,在②和③处通过 DataSourceUtils.releaseConnection()释放连接。所有JdbcTemplate开放的数据访问API最终都是直接或间 接由execute(StatementCallback
正是因为JdbcTemplate严谨的获取连接及释放连接的模式化流程保证了JdbcTemplate对数据连接泄漏问题的免疫性。所以,如有可能尽量 使用JdbcTemplate、HibernateTemplate等这些模板进行数据访问操作,避免直接获取数据连接的操作。
使用TransactionAwareDataSourceProxy
如果不得已要显式获取数据连接,除了使用DataSourceUtils获取事务上下文绑定的连接外,还可以通过 TransactionAwareDataSourceProxy对数据源进行代理。数据源对象被代理后就具有了事务上下文感知的能力,通过代理数据源的 getConnection()方法获取连接和使用DataSourceUtils.getConnection()获取连接的效果是一样的。
下面是使用TransactionAwareDataSourceProxy对数据源进行代理的配置:
01 < xml version="1.0" encoding="UTF-8" >
02 03 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 04 … 05 http://www.springframework.org/schema/tx 06 http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> 07 08 09 10 11 12 destroy-method="close" 13 p:driverClassName="${jdbc.driverClassName}" 14 p:url="${jdbc.url}" 15 p:username="${jdbc.username}" 16 p:password="${jdbc.password}"/> 17 18 19 20 class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy" 21 p:targetDataSource-ref="originDataSource" /> 22 23 24 class="org.springframework.jdbc.core.JdbcTemplate" 25 p:dataSource-ref="dataSource"/> 26 27 28 class="org.springframework.jdbc.datasource.DataSourceTransactionManager" 29 p:dataSource-ref="dataSource"/> 30 31
对数据源进行代理后,我们就可以通过数据源代理对象的getConnection()获取事务上下文中绑定的数据连接了。因此,如果数据源已经进行了 TransactionAwareDataSourceProxy的代理,而且方法存在事务上下文,那么代码清单10-19的代码也不会生产连接泄漏的问 题。
其他数据访问技术的等价类
理解了Spring JDBC的数据连接泄漏问题,其中的道理可以平滑地推广到其他框架中去。Spring为每个数据访问技术框架都提供了一个获取事务上下文绑定的数据连接(或其衍生品)的工具类和数据源(或其衍生品)的代理类。
表10-5列出了不同数据访问技术对应DataSourceUtils的等价类。
表10-5 不同数据访问框架DataSourceUtils的等价类
数据访问技术框架 连接(或衍生品)获取工具类
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
表10-6列出了不同数据访问技术框架下TransactionAwareDataSourceProxy的等价类。
表10-6 不同数据访问框架TransactionAwareDataSourceProxy的等价类
数据访问技术框架 连接(或衍生品)获取工具类
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.TransactionAwarePersistenceManagerFac