欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

关于TransactionAwareDataSourceProxy 博客分类: Spring4.X spring 

程序员文章站 2024-02-10 11:53:16
...
数据连接泄露是个很头疼的问题,框架Spring也提供了很多种办法来避免这个问题,比如使用Template,当然其背后是DataSourceUtils.这里还有另外一种办法,使用TransactionAwareDataSourceProxy.通过TransactionAwareDataSourceProxy对数据源进行代理后,数据源对象就有了事务上下文感知的能力了。看源码会发现,其实它还是使用的DataSourceUtils. 哈哈,是不是觉得其实是在围着一个原点打转?

这里只取一部分TransactionAwareDataSourceProxy源码来看看,如下。看到这里明白了吧。
Connection actualTarget = this.target;
                if(actualTarget == null) {
                    actualTarget = DataSourceUtils.doGetConnection(this.targetDataSource);
                }


然后看看在beans.xml中的配置,配置很简单,就一个引用,如下:
<bean id="originalDataSource" class="org.apache.commons.dbcp.BasicDataSource"
          destroy-method="close"
          p:driverClassName="${jdbc.driverClassName}"
          p:url="${jdbc.url}"
          p:username="${jdbc.username}"
          p:password="${jdbc.password}"/>
    <!-- 对数据源进行代理, 使数据源具有事务上下文感知能力-->

    <bean id="dataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy"
          p:targetDataSource-ref="originalDataSource"/>


配好了后,在代码中使用如下:
//使用TransactionAwareDataSourceProxy对数据源进行代理, 使数据源具有事务上下文感知能力
        TransactionAwareDataSourceProxy dataSourceProxy = (TransactionAwareDataSourceProxy) ctx.getBean("dataSource");
//通过代理对象来获取数据源对象。
        BasicDataSource basicDataSource = (BasicDataSource) dataSourceProxy.getTargetDataSource();


还可以通过代理对象的getConnection()方法来获取事务上下文中绑定的数据连接。注意下面的源码。是不是看到了事务同步管理器的身影?
protected boolean shouldObtainFixedConnection(DataSource targetDataSource) {
        return !TransactionSynchronizationManager.isSynchronizationActive() || !this.reobtainTransactionalConnections;
    }

这里就说为什么可以避免连接泄露。

这里用的BasicDataSource,其他DataSource也是类似的。
相关标签: spring