-
Notifications
You must be signed in to change notification settings - Fork 8.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Oracle10g 使用Driud连接池后,会时不时出现java.sql.SQLException: connection holder is null错误的疑似BUG #2046
Comments
收到,你能提供一下用的druid版本信息么?好让我尽快做验证。 |
@wenshao druid版本信息为1.1.4。 PS:我这里使用的是在tomcat中配置的JNDI,然后在spring中配置的org.springframework.jndi.JndiObjectFactoryBean的dataSource,然后使用dataSource配置的JdbcTemplate。由于系统架构遗留问题,系统中使用了JdbcTemplate和InitialContext.lookup("jdbc/XXXXX")的两种连接方式。 |
我也遇到了这个问题,使用的版本是 1.1.2
不过我的数据库是 mysql 我在本地也可以复现 我是 clojure 环境下 (defonce stat-filter
(doto (StatFilter.)
(.setSlowSqlMillis (int-env :mysql-slow-mills 1000))
(.setLogSlowSql true)))
(doto (DruidDataSource.)
(.setUrl (format "jdbc:mysql:%s"
(env :db-subname "//127.0.0.1:3306/uluru")))
(.setUsername (env :db-username "root"))
(.setPassword (env :db-password "xxx"))
(.setKeepAlive true)
(.setInitialSize 10)
(.setMinIdle 10)
(.setMaxActive (max
(quot
(config/server-threads)
2)
150))
(.setMaxWait 60000) ;; 配置获取连接等待超时的时间
(.setValidationQueryTimeout 1)
(.setProxyFilters [stat-filter])
(.setTimeBetweenEvictionRunsMillis 30000) ;; 间隔多久才进行一次检测,检测需要关闭的空闲连接
(.setMinEvictableIdleTimeMillis 30000) ;; 一个连接在池中最小生存的时间,30s
(.setTimeBetweenLogStatsMillis 300000) ;; 每隔 5 分钟输出日志
(.setValidationQuery "SELECT 'x'")
(.setTestWhileIdle true)
(.setTestOnBorrow false)
(.setTestOnReturn false)
(.setPoolPreparedStatements false)) my.conf
会报错
的确是超过了 60s 但是貌似检测并没有生效。然后链接被 mysql 收回,连接池依然使用了这个已经被收回的链接,就有了这个异常。 |
@TinyYang 我测试的结果是,1.1.2 的版本 testOnBorrow 和 testOnReturn 也是无效的,并没有看到 |
@wenshao 温少,我这两天debug跟踪,发现了一些情况,OracleExceptionSorter是可以起作用的,但是我查出来现在出现问题的是在这个位置com.alibaba.druid.pool.DruidPooledConnection的347行
` JdbcTemplate在请求数据库访问的时候,调用了prepareStatement,然后首先进入的是checkState()这个方法,问题就是出在,当holder为空时,直接就会到checkStateInternal中抛出异常,而此时是没有到handleException(ex)中的,这个handleException(ex);里面才是OracleExceptionSorter处理的地方。 丢失连接后,肯定是走了pooledConnection.disable(t);这个方法,不然holder不会置为空,因此现在问题就是在于为什么已经disable的holder后续还是会被调用到,导致在进入checkState()方法时就报错了。由于holder怎么调用获取的调度算法我这里还没时间研究,因此希望能给温少提供一点方向和思路,这个问题已经困扰我们很久了,谢谢! @paomian mysql我现在接触得不多,不过感觉你的问题可能和我的差不多,可能也是出在同一个地方。 |
@TinyYang 具体的代码我没有仔细看,目前使用了暴力增加 mysql 的链接空闲过期时间来缓解这个问题,基本奏效。还是等官方的解释吧。 |
@TinyYang 感觉是因为JdbcTemplate持有了一个连接已经关闭的PreparedStatement |
@wenshao 温少,感谢您的反馈!但是这样就有点问题了,spring的JdbcTemplate是自动释放连接的啊。我的spring的配置如下: 这样的设置,应该都是正常的啊,JdbcTemplate都会自动关闭,因为如果JdbcTemplate持有了一个连接已经关闭的PreparedStatement的话,应该会系统直接崩溃不能运行,但是只是偶尔会出现连接丢失,就好像连接池里面20个连接,其中一个连接丢失了,就只会随机在用到那个丢失连接的时候,就会出错。现在我个人觉得好像就是在调用连接池的连接的时候,引用到了无效的那个连接。 再次感谢您的反馈与帮助! |
@TinyYang 能否微信找我直接快速交流 wenshaojin |
@TinyYang 我通过kill session没有模拟出你的问题,能否帮忙构造一个场景帮我重现问题 |
@wenshao 嗨,wenshao,今天从dbcp切换到druid数据库连接池,在测试过程中,同样抛出了connection holder is null的错误。看了你之前给的解决方案,关闭removeAbandoned配置,可以解决问题。但是不太明白的是,druid有对这个配置做什么处理吗?同样这个配置,在dbcp下是正常的,还请wenshao给些思路,谢谢 |
申请连接长时间不适用被关闭了,所以导致connection holder is null错误,removeAbandoned一般用于故障诊断时才打开,你为什么需要使用这个选项? |
@wenshao 这个配置的目的是防止连接泄漏,所以中项目中配置了这一项 |
请问有解决没 |
问题解决了吗 |
@wenshao 温少,我也遇到了这样的问题,出现的场景是,数据库升级重启之后,一直在报这个错。能帮忙分析下吗?
|
最近在系统长时间运行后,如果在Oracle后台,KILL了一个Session之后,由于系统还是在频繁使用连接,我把timeBetweenEvictionRunsMillis设置为10秒,但是好像还是不会把这种失效的链接从连接池中清除掉。还是会继续让业务调用,造成经常出现connection holder is null的错误,同时ExceptionSorter好像也没有把这种报错的连接抛弃掉,请问这个是否是druid的BUG?还是说我的配置哪里有问题呢?配置和错误信息如下:
配置如下:
<Resource
name="jdbc/XXXXX"auth="Container"
factory="com.alibaba.druid.pool.DruidDataSourceFactory"
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@X.X.X.X:1521:orcl"
username="USERNAME"
password="PASSWORD"
initialSize="20"
minIdle="0"
maxActive="100"
maxWait="1000"
removeabandoned="false"
removeabandonedtimeout="18000"
validationQuery="select 1 from dual"
testWhileIdle="true"
testOnBorrow="false"
testOnReturn="false"
timeBetweenEvictionRunsMillis="10000"
poolPreparedStatements="true"
maxOpenPreparedStatements="100"
filters="stat,log4j" />`
错误信息如下:
SQL [SELECT CO1,CO2,CO3,CO4,CO5 FROM TABLE1 WHERE KEY1='111' order by CO1]; SQL state [null]; error code [0]; connection holder is null; nested exception is java.sql.SQLException: connection holder is null
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:83)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:406)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:455)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:463)
at org.springframework.jdbc.core.JdbcTemplate.queryForList(JdbcTemplate.java:494)
........
Caused by: java.sql.SQLException: ORA-00028: your session has been killed
The text was updated successfully, but these errors were encountered: