项目依赖
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>18.15.0.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.6</version>
</dependency>
测试代码
Thread(
Runnable {
var druidDataSource: DruidDataSource? = null
val connectBO = ConnectBO("jdbc:oracle:thin:@10.10.xx.xx:1521/rac", "username", "errorpassword")
try {
druidDataSource = createDataSource(connectBO) as DruidDataSource
druidDataSource.getConnection(2_000).use {
println(it)
}
} catch (e: Exception) {
println(String.format("test connect error, url:[%s]", connectBO.url))
} finally {
druidDataSource?.close()
}
}
).start()
Thread.sleep(100_000)
}
fun createDataSource(connectBO: ConnectBO): DataSource {
val props = Properties().apply {
this[DruidDataSourceFactory.PROP_DRIVERCLASSNAME] = oracle.jdbc.OracleDriver::class.qualifiedName!!
this[DruidDataSourceFactory.PROP_USERNAME] = connectBO.username
this[DruidDataSourceFactory.PROP_PASSWORD] = connectBO.password
this[DruidDataSourceFactory.PROP_URL] = connectBO.url
}
props.setProperty(DruidDataSourceFactory.PROP_INITIALSIZE, "1")
return DruidDataSourceFactory.createDataSource(props)
}
data class ConnectBO(val url: String, val username: String, val password: String)
问题现象
连接池中的CreateConnectionThread未正常关闭,持续创建连接并打印报错日志:
十一月 10, 2021 11:16:18 上午 com.alibaba.druid.pool.DruidDataSource error
严重: create connection SQLException, url: jdbc:oracle:thin:@10.10.xx.xx:1521/rac, errorCode 1017, state 72000
java.sql.SQLException: ORA-01017: invalid username/password; logon denied
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:494)
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:441)
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:436)
at oracle.jdbc.driver.T4CTTIfun.processError(T4CTTIfun.java:1110)
at oracle.jdbc.driver.T4CTTIoauthenticate.processError(T4CTTIoauthenticate.java:552)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:540)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:256)
at oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.java:501)
at oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.java:1297)
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:694)
at oracle.jdbc.driver.PhysicalConnection.connect(PhysicalConnection.java:782)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:39)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:704)
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1657)
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1723)
at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2801)
原因分析
根据异常堆栈:
2021-10-11 11:39:24,343 ERROR - [com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2803)] create connection SQLException, url: jdbc:oracle:thin:@10.10.60.52:1521/pdb1, errorCode 17002, state 08006
java.sql.SQLRecoverableException: IO 错误: The Network Adapter could not establish the connection
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:774)
at oracle.jdbc.driver.PhysicalConnection.connect(PhysicalConnection.java:688)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:39)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:691)
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1657)
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1723)
at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2801)
Caused by: oracle.net.ns.NetException: The Network Adapter could not establish the connection
at oracle.net.nt.ConnStrategy.execute(ConnStrategy.java:523)
at oracle.net.resolver.AddrResolution.resolveAndExecute(AddrResolution.java:521)
at oracle.net.ns.NSProtocol.establishConnection(NSProtocol.java:660)
at oracle.net.ns.NSProtocol.connect(NSProtocol.java:286)
at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:1438)
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:518)
... 6 more
Caused by: java.io.IOException: Operation interrupted, socket connect lapse 0 ms. /10.10.xx.xx 1521 0 1 true
at oracle.net.nt.TcpNTAdapter.connect(TcpNTAdapter.java:209)
at oracle.net.nt.ConnOption.connect(ConnOption.java:161)
at oracle.net.nt.ConnStrategy.execute(ConnStrategy.java:470)
... 11 more
Caused by: java.io.InterruptedIOException: Operation interrupted
at oracle.net.nt.TimeoutSocketChannel.handleInterrupt(TimeoutSocketChannel.java:311)
at oracle.net.nt.TimeoutSocketChannel.<init>(TimeoutSocketChannel.java:84)
at oracle.net.nt.TcpNTAdapter.connect(TcpNTAdapter.java:169)
... 13 more
ojdbc8驱动在TimeoutSocketChannel#handleInterrupt方法中清除了线程中断标志,导致Druid的CreateConnectionThread无法在run方法中正常结束。
使用ojdbc6驱动则没有这个问题,Druid能否处理这种问题呢?
4条答案
按热度按时间2nc8po8w1#
我现在升级到1.2.7了,还会有这个问题
vs3odd8k2#
使用MySQL驱动也遇到了CreateConnectionThread无法退出的问题。
驱动依赖:
测试代码:
当连接的数据库test1不存在时,调用close方法关闭连接池后,由于com.mysql.cj.jdbc.ConnectionImpl#connectWithRetries()方法的第906行捕捉并忽略了InterruptedException,导致Druid的CreateConnectionThread无法退出。
解决建议
能否在CreateConnectionThread的run方法中使用DruidDataSource的closed变量作为退出标识让CreateConnectionThread正确退出。
kpbpu0083#
也遇到了 相同的问题,目前就只能设置 Druid 连接失败之后不再自动重连,Oracle 在里面把中断信号给丢了,或者说发送给 创建连接的线程的中断信号给Oracle给捕获了,从Oracle里面的逻辑上来看,Oracle 有自己的中断任务,如果中断任务不存在,会把中断信号给吞了。也是建议使用连接池的状态来控制创建线程和销毁线程的生命周期,中断信号一旦被其他线程,捕获之后是不可控的。
wn9m85ua4#
这个问题代码合入了吗?最新版本代码看着没合入: