选择显示字体大小

dbcp代码研读以及就数据库连接失效的解决


问题

网上很多评论说dbcp有很多bug,但是都没有指明是什么bug,只有一部分人说数据库如果因为某种原因断掉后再dbcp取道的连接都是失效的连接,而没有重新取。就此研读了一下dbcp的代码,共享之。

分析

dbcp使用apache的对象池objectpool作为连接池的实现,有以下主要的方法

object borrowobject() throws exception;从对象池取得一个有效对象

void returnobject(object obj) throws exception;使用完的对象放回对象池

void invalidateobject(object obj) throws exception;使对象失效

void addobject() throws exception;生成一个新对象


objectpool的一个实现就是genericobjectpool,这个类使用对象工厂poolableobjectfactory实现对象的生成,失效检查等等功能,以其实现数据库连接工厂poolableconnectionfactory做以说明,主要方法:

     object makeobject() throws exception; 使用connectionfactory生成新连接

     void destroyobject(object obj) throws exception;关闭连接

     boolean validateobject(object obj); 验证连接是否有效,如果_validationquery不空,则使用该属性作为验证连接是否有效的sql语句,查询数据库

     void activateobject(object obj) throws exception;激活连接对象

     void passivateobject(object obj) throws exception; 关闭连接生成过的statement和resultset,使连接处于非活动状态



而genericobjectpool有几个主要属性

     _timebetweenevictionrunsmillis:失效检查线程运行时间间隔,默认-1

     _maxidle:对象池中对象最大个数

     _minidle:对象池中对象最小个数

     _maxactive:可以从对象池中取出的对象最大个数,为0则表示没有限制,默认为8

在构造genericobjectpool时,会生成一个内嵌类evictor,实现自runnable接口。如果_timebetweenevictionrunsmillis大于0,每过_timebetweenevictionrunsmillis毫秒evictor会调用evict()方法,检查对象的闲置时间是否大于 _minevictableidletimemillis毫秒(_minevictableidletimemillis小于等于0时则忽略,默认为30分钟),是则销毁此对象,否则就激活并校验对象,然后调用ensureminidle方法检查确保池中对象个数不小于_minidle。在调用returnobject方法把对象放回对象池,首先检查该对象是否有效,然后调用poolableobjectfactory 的passivateobject方法使对象处于非活动状态。再检查对象池中对象个数是否小于_maxidle,是则可以把此对象放回对象池,否则销毁此对象

还有几个很重要的属性,_testonborrow、_testonreturn、_testwhileidle,这些属性的意义是取得、返回对象和空闲时是否进行验证,检查对象是否有效,默认都为false即不验证。所以当使用dbcp时,数据库连接因为某种原因断掉后,再从连接池中取得连接又不进行验证,这时取得的连接实际已经时无效的数据库连接了。网上很多说dbcp的bug应该都是如此吧,只有把这些属性设为true,再提供_validationquery语句就可以保证数据库连接始终有效了oracle数据库可以使用select count(*) from dual,不过dbcp要求_validationquery语句查询的记录集必须不为空,可能这也可以算一个小小的bug,其实只要_validationquery语句执行通过就可以了。

注意事项

所以使用dbcp连接池放必须注意构造genericobjectpool对象时

     validationquery:select count(*) from dual

       _testonborrow、_testonreturn、_testwhileidle:最好都设为true

       _minevictableidletimemillis:大于0 ,进行连接空闲时间判断,或为0,对空闲的连接不进行验证

     _timebetweenevictionrunsmillis:失效检查线程运行时间间隔,如果小于等于0,不会启动检查线程



 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons