`
ynztpwl
  • 浏览: 55870 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

分析Atomikos数据连接池源码,弄清testQuery

 
阅读更多

作者:fbysss
msn:jameslastchina@hotmail.com
blog:blog.csdn.net/fbysss
声明:本文由fbysss原创,转载请注明出处
关键字:Atomikos数据连接池

前言

Atomikos数据连接池,国内有一些应用,但testQuery这个属性,在网上均是简单配置,并没有做特殊说明。通过对Atomikos源码的分析,发现这里很有学问。

分析

我们使用的数据源是AtomikosDataSourceBean,在其doInit方法中,会调用AtomikosXAConnectionFactorycreatePooledConnection方法,该方法会返回一个AtomikosXAPooledConnection连接。

AtomikosXAPooledConnectionAbstractXPooledConnection的一个子类,AbstractXPooledConnection中,在调用createConnectionProxy时,会调用testUnderlyingConnection方法,用于进行测试。

在AtomikosDataSourceBeangetConnection时,调用connectionPool的borrowConnection方法从而调用AbstractXPooledConnection中的createConnectionProxy,从而调用testUnderlyingConnection方法。

可以看testUnderlyingConnection中的关键代码,一旦设置了testQuery,每次getConnection的时候,就会连接查询一次(通过jprofiler也可以检测出来):

如果失败,抛出CreateConnectionException异常。

注意ConnectionPoolborrowConnection方法,其中有一段:

可以看到,其做的事情,就是遍历连接池中的连接,一个一个的测试。注意ret = xpc.createConnectionProxy ( hmsg ),一旦该方法抛出CreateConnectionException,就执行it.remove();即将该连接从连接池中删除。

如果设置了testQuery属性,每次获取连接时testQuery,能够保证应用服务器启动之后,与数据库连接暂时中断之后,能够在下一次请求时,自动重新建立连接。

连接池是如何自动建立连接的呢?其实就是简单的把无效的连接一个一个删掉,直到全部删光了,池里面没有有效(poolAvailableSize==0,是根据连接的isTerminated状态来判断的,而不是是否被重置过)的连接了,这样根据连接池的机制,就会调用growPool方法去请求新的连接。

但是这样有性能消耗,而且还不小。对于网站展示部分,不需要实时去检测,可以考虑采用定时检测的方法:

n 首先,保证testQuery为空,不配置。

n 创建一个DbPoolMonitorService类,实现ApplicationContextAware接口,这样应用启动时,会自动注入ApplicationContext对象。这样,可以在service中,调用getBean方法,获取AtomikosDataSourceBean的实例,

AtomikosDataSourceBean ads = (AtomikosDataSourceBean)ctx.getBean(“jtaDataSource”);

然后,ads中能够获得minPoolSize/maxPoolSize/availablePoolSize/totalPoolSize等属性,可以做一个界面来监测数据连接池的使用和配置情况,甚至可以动态修改这些属性。

n 做一个定时器,调用一个DbPoolMonitorService定期去手工test。使用SELECT 1 语句即可。

n 注意:try 部分ads.setTestQuery (“SELECT 1”);然后调用BaseDao的实例去执行一句话,依然可以使”SELECT 1” 。finally部分ads.setTestQuery(null),以保证不对其他部分造成后续影响。

n 可根据用户访问量,来决定定时周期,一般10分钟左右即可。这样,避免了每次获取连接去做一次检测操作,又能够将故障限制在一定时间范围内。是一个较好的折衷做法。

补充:我们再看ret = xpc.createConnectionProxy ( hmsg )这句话,如果这时候DB和WebAppServer的网络链路已经正常,DB正常运行,返回将不是空,会退出循环。这样,如果连接池中的连接是多个,则只会生成1个新的连接,如果要保证连接池机制的效果,需要在写监控程序的时候,去取得所有有效连接,循环test。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics