最新消息:

JAVA连接池导致的超高回滚率 – rlbk=1

未分类 admin 3220浏览 0评论

作者:eygle 发布在 eygle.com

在客户的数据库中,我们发现事务数量非常高,最后确认是由于回滚导致的。

经过检查发现在JAVA连接池的数据库活动性检查时,每次执行查询之后,都会执行一次回滚,从而导致了数据库回滚率超高:

=====================
PARSING IN CURSOR #1 len=18 dep=0 uid=26 oct=3 lid=26 tim=1292816994316916 hv=3876449241 ad=’ab946d24′
SELECT 1 FROM DUAL
END OF STMT
PARSE #1:c=0,e=19,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,tim=1292816994316914
EXEC #1:c=0,e=9,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,tim=1292816994316979
WAIT #1: nam=’SQL*Net message to client’ ela= 1 p1=675562835 p2=1 p3=0
WAIT #1: nam=’SQL*Net message from client’ ela= 116 p1=675562835 p2=1 p3=0
WAIT #1: nam=’SQL*Net message to client’ ela= 1 p1=675562835 p2=1 p3=0
WAIT #1: nam=’SQL*Net message from client’ ela= 128 p1=675562835 p2=1 p3=0
WAIT #1: nam=’SQL*Net message to client’ ela= 1 p1=675562835 p2=1 p3=0
FETCH #1:c=0,e=37,p=0,cr=3,cu=0,mis=0,r=1,dep=0,og=4,tim=1292816994317363
WAIT #1: nam=’SQL*Net message from client’ ela= 118 p1=675562835 p2=1 p3=0
WAIT #1: nam=’SQL*Net message to client’ ela= 1 p1=675562835 p2=1 p3=0
WAIT #1: nam=’SQL*Net message from client’ ela= 96 p1=675562835 p2=1 p3=0
STAT #1 id=1 cnt=1 pid=0 pos=1 obj=222 op=’TABLE ACCESS FULL DUAL (cr=3 r=0 w=0 time=16 us)’
WAIT #1: nam=’SQL*Net message to client’ ela= 1 p1=675562835 p2=1 p3=0
WAIT #1: nam=’SQL*Net message from client’ ela= 97 p1=675562835 p2=1 p3=0
XCTEND rlbk=1, rd_only=1
WAIT #0: nam=’SQL*Net message to client’ ela= 1 p1=675562835 p2=1 p3=0
WAIT #0: nam=’SQL*Net message from client’ ela= 96 p1=675562835 p2=1 p3=0
WAIT #0: nam=’SQL*Net message to client’ ela= 1 p1=675562835 p2=1 p3=0
WAIT #0: nam=’SQL*Net message from client’ ela= 113 p1=675562835 p2=1 p3=0
WAIT #0: nam=’SQL*Net message to client’ ela= 2 p1=675562835 p2=1 p3=0
WAIT #0: nam=’SQL*Net message from client’ ela= 96 p1=675562835 p2=1 p3=0
WAIT #1: nam=’SQL*Net message to client’ ela= 2 p1=675562835 p2=1 p3=0
WAIT #1: nam=’SQL*Net message from client’ ela= 117 p1=675562835 p2=1 p3=0
=====================

DBCP连接池的一些设置参数如下
(转自 http://agapple.iteye.com/blog/791943 ):

sql validate 配置

<property name= “testWhileIdle” ><value> true </value></property>
<property name= “testOnBorrow” ><value> false </value></property>
<property name= “testOnReturn” ><value> false </value></property>
<property name= “validationQuery” ><value>select sysdate from dual</value></property>
<property name= “validationQueryTimeout” ><value>1</value></property>
<property name= “timeBetweenEvictionRunsMillis” ><value>30000</value></property>
<property name= “numTestsPerEvictionRun” ><value>16</value></property>

参数说明
dbcp 是采用了 commons-pool 做为其连接池管理, testOnBorrow,testOnReturn, testWhileIdle 是 pool 是提供的几种校验机制,通过外部钩子的方式回调 dbcp 的相关数据库链接 (validationQuery) 校验 , dbcp 相关外部钩子类: PoolableConnectionFactory, 继承于 common-pool PoolableObjectFactory , dbcp 通过 GenericObjectPool 这一入口,进行连接池的 borrow,return 处理。

具体参数描述:
1. testOnBorrow : 顾明思义,就是在进行borrowObject进行处理时,对拿到的connection进行validateObject校验
2. testOnReturn : 顾明思义,就是在进行returnObject对返回的connection进行validateObject校验,个人觉得对数据库连接池的管理意义不大
3. testWhileIdle : 关注的重点,GenericObjectPool中针对pool管理,起了一个 异步Evict的TimerTask定时线程进行控制 ( 可通过设置参数 timeBetweenEvictionRunsMillis>0), 定时对线程池中的链接进行validateObject校验,对无效的链接进行关闭后,会调用ensureMinIdle,适当建立链接保证最小的minIdle连接数。
4. timeBetweenEvictionRunsMillis, 设置的Evict线程的时间,单位ms,大于0才会开启evict检查线程
5. validateQuery , 代表检查的sql
6. validateQueryTimeout , 代表在执行检查时,通过statement设置,statement.setQueryTimeout(validationQueryTimeout)
7. numTestsPerEvictionRun ,代表每次检查链接的数量,建议设置和maxActive一样大,这样每次可以有效检查所有的链接.

 

相关文章|Related Articles

评论数量(1)|Add Comments

本文网址:

转载请注明:爱开源 » JAVA连接池导致的超高回滚率 – rlbk=1

您必须 登录 才能发表评论!