Java 由于长时间运行的连接而阻塞线程?
我必须维护的一个旧Java偶尔会停止响应。我设法获得了几个线程堆栈跟踪,大多数线程都像这样被阻塞,试图获得连接:Java 由于长时间运行的连接而阻塞线程?,java,oracle,tomcat,jdbc,Java,Oracle,Tomcat,Jdbc,我必须维护的一个旧Java偶尔会停止响应。我设法获得了几个线程堆栈跟踪,大多数线程都像这样被阻塞,试图获得连接: "tomcat-http-8180-168" - Thread t@10137 java.lang.Thread.State: BLOCKED at oracle.jdbc.pool.OracleImplicitConnectionCache.retrieveCacheConnection(OracleImplicitConnectionCache.java:566)
"tomcat-http-8180-168" - Thread t@10137
java.lang.Thread.State: BLOCKED
at oracle.jdbc.pool.OracleImplicitConnectionCache.retrieveCacheConnection(OracleImplicitConnectionCache.java:566)
- waiting to lock <566080> (a oracle.jdbc.pool.OracleImplicitConnectionCache) owned by "Thread-6" t@29
“tomcat-http-8180-168”-线程t@10137
java.lang.Thread.State:已阻止
位于oracle.jdbc.pool.OracleImplicitConnectionCache.retrieveCacheConnection(OracleImplicitConnectionCache.java:566)
-正在等待“Thread-6”拥有的锁(oracle.jdbc.pool.OracleImplicitConnectionCache)t@29
持有锁的螺纹显示:
"Thread-6" - Thread t@29
java.lang.Thread.State: BLOCKED
at oracle.jdbc.driver.PhysicalConnection.closeLogicalConnection(PhysicalConnection.java:3849)
- waiting to lock <146da30> (a oracle.jdbc.driver.T4CConnection) owned by "tomcat-http-8180-369" t@17665
at oracle.jdbc.driver.LogicalConnection.cleanupAndClose(LogicalConnection.java:304)
at oracle.jdbc.pool.OracleImplicitConnectionCache.closeCheckedOutConnection(OracleImplicitConnectionCache.java:1392)
at oracle.jdbc.pool.OracleImplicitConnectionCacheThread.runAbandonedTimeout(OracleImplicitConnectionCacheThread.java:250)
- locked <566080> (a oracle.jdbc.pool.OracleImplicitConnectionCache)
at oracle.jdbc.pool.OracleImplicitConnectionCacheThread.run(OracleImplicitConnectionCacheThread.java:81)
“螺纹-6”-螺纹t@29
java.lang.Thread.State:已阻止
位于oracle.jdbc.driver.PhysicalConnection.closeLogicalConnection(PhysicalConnection.java:3849)
-等待“tomcat-http-8180-369”拥有的锁(oracle.jdbc.driver.T4CConnection)t@17665
位于oracle.jdbc.driver.LogicalConnection.cleanupAndClose(LogicalConnection.java:304)
在oracle.jdbc.pool.OracleImplicitConnectionCache.closeCheckedOutConnection(OracleImplicitConnectionCache.java:1392)
在oracle.jdbc.pool.OracleImplicitConnectionCacheThread.runaboutedtimeout(OracleImplicitConnectionCacheThread.java:250)
-锁定(oracle.jdbc.pool.OracleImplicitConnectionCache)
在oracle.jdbc.pool.OracleImplicitConnectionCacheThread.run(OracleImplicitConnectionCacheThread.java:81)
此线程似乎负责关闭已放弃的连接,而它本身在等待另一个线程完成时被阻塞:
"tomcat-http-8180-369" - Thread t@17665
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at oracle.net.ns.Packet.receive(Packet.java:282)
at oracle.net.ns.DataPacket.receive(DataPacket.java:103)
at oracle.net.ns.NetInputStream.getNextPacket(NetInputStream.java:230)
at oracle.net.ns.NetInputStream.read(NetInputStream.java:175)
at oracle.net.ns.NetInputStream.read(NetInputStream.java:100)
at oracle.net.ns.NetInputStream.read(NetInputStream.java:85)
at oracle.jdbc.driver.T4CSocketInputStreamWrapper.readNextPacket(T4CSocketInputStreamWrapper.java:122)
at oracle.jdbc.driver.T4CSocketInputStreamWrapper.read(T4CSocketInputStreamWrapper.java:78)
at oracle.jdbc.driver.T4CSocketInputStreamWrapper.readB1(T4CSocketInputStreamWrapper.java:149)
at oracle.jdbc.driver.T4CMAREngine.buffer2Value(T4CMAREngine.java:2393)
at oracle.jdbc.driver.T4CMAREngine.unmarshalSB8(T4CMAREngine.java:1401)
at oracle.jdbc.driver.T4C8TTILob.readRPA(T4C8TTILob.java:837)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:292)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:186)
at oracle.jdbc.driver.T4C8TTIClob.read(T4C8TTIClob.java:240)
at oracle.jdbc.driver.T4CConnection.getChars(T4CConnection.java:3015)
- locked <146da30> (a oracle.jdbc.driver.T4CConnection)
at oracle.sql.CLOB.getChars(CLOB.java:402)
at oracle.jdbc.driver.OracleClobReader.needChars(OracleClobReader.java:187)
at oracle.jdbc.driver.OracleClobReader.read(OracleClobReader.java:142)
at java.io.Reader.read(Reader.java:123)
at oracle.jdbc.driver.ClobAccessor.getString(ClobAccessor.java:291)
at oracle.jdbc.driver.T4CClobAccessor.getString(T4CClobAccessor.java:481)
at oracle.jdbc.driver.OracleResultSetImpl.getString(OracleResultSetImpl.java:1251)
- locked <146da30> (a oracle.jdbc.driver.T4CConnection)
at oracle.jdbc.driver.OracleResultSet.getString(OracleResultSet.java:494)
“tomcat-http-8180-369”-线程t@17665
java.lang.Thread.State:可运行
位于java.net.SocketInputStream.socketRead0(本机方法)
位于java.net.SocketInputStream.read(SocketInputStream.java:129)
位于oracle.net.ns.Packet.receive(Packet.java:282)
位于oracle.net.ns.DataPacket.receive(DataPacket.java:103)
位于oracle.net.ns.NetInputStream.getNextPackage(NetInputStream.java:230)
位于oracle.net.ns.NetInputStream.read(NetInputStream.java:175)
位于oracle.net.ns.NetInputStream.read(NetInputStream.java:100)
位于oracle.net.ns.NetInputStream.read(NetInputStream.java:85)
位于oracle.jdbc.driver.T4CSocketInputStreamWrapper.readnextPackage(T4CSocketInputStreamWrapper.java:122)
位于oracle.jdbc.driver.t4CSocketingInputStreamWrapper.read(t4CSocketingInputStreamWrapper.java:78)
位于oracle.jdbc.driver.T4CSocketInputStreamWrapper.readB1(T4CSocketInputStreamWrapper.java:149)
位于oracle.jdbc.driver.T4CMAREngine.buffer2Value(T4CMAREngine.java:2393)
位于oracle.jdbc.driver.T4CMAREngine.unmarshalSB8(T4CMAREngine.java:1401)
位于oracle.jdbc.driver.T4C8TTILob.readRPA(T4C8TTILob.java:837)
位于oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:292)
位于oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:186)
位于oracle.jdbc.driver.T4C8TTIClob.read(T4C8TTIClob.java:240)
位于oracle.jdbc.driver.T4CConnection.getChars(T4CConnection.java:3015)
-锁定(一个oracle.jdbc.driver.T4CConnection)
位于oracle.sql.CLOB.getChars(CLOB.java:402)
位于oracle.jdbc.driver.OracleClobReader.needChars(OracleClobReader.java:187)
位于oracle.jdbc.driver.OracleClobReader.read(OracleClobReader.java:142)
在java.io.Reader.read(Reader.java:123)
位于oracle.jdbc.driver.ClobAccessor.getString(ClobAccessor.java:291)
位于oracle.jdbc.driver.T4CClobAccessor.getString(T4CClobAccessor.java:481)
位于oracle.jdbc.driver.OracleResultSetImpl.getString(OracleResultSetImpl.java:1251)
-锁定(一个oracle.jdbc.driver.T4CConnection)
位于oracle.jdbc.driver.OracleResultSet.getString(OracleResultSet.java:494)
最后一个线程正在运行一个繁重的查询。这也是为什么它被认为是废弃的,Tomcat正试图关闭它,但它似乎无法关闭,因为它正在使用中,并且有一个锁
我不明白为什么:
- Oracle无法关闭连接
- 在关闭放弃的连接之前,其他线程无法从池中获取连接
我还研究了其他可能的原因,比如长时间的完整GC,但是启用了GC日志记录,没有长时间的停顿来解释这一点
提前感谢。不支持Oracle隐式连接缓存。您必须使用通用连接池(UCP),它是ICC的替代品。您可以下载并查看白皮书以了解更多详细信息
<Resource
name="jdbc/MainDBPool"
AutoCommit="true"
defaultReadOnly="false"
driverClassName="oracle.jdbc.OracleDriver"
factory="oracle.jdbc.pool.OracleDataSourceFactory"
fairQueue="false"
initialSize="10"
jdbcInterceptors="ConnectionState;StatementFinalizer"
jmxEnabled="true"
logAbandoned="false"
maxActive="100"
maxIdle="75"
maxWait="30000"
minEvictableIdleTimeMillis="5000"
minIdle="10"
removeAbandoned="true"
removeAbandonedTimeout="60"
testOnBorrow="false"
testOnReturn="false"
testWhileIdle="false"
timeBetweenEvictionRunsMillis="5000"
type="oracle.jdbc.pool.OracleDataSource"
connectionCachingEnabled="true"
connectionCacheName="tomcatConnectionCache1"
fastConnectionFailoverEnabled="true"
implicitCachingEnabled="true"
connectionCacheProperties="(ValidateConnection=true, PropertyCheckInterval=60, AbandonedConnectionTimeout=300, InitialLimit=10, MinLimit=30, MaxLimit=200, ConnectionWaitTimeout=30, InactivityTimeout=300)"
useEquals="false"
validationInterval="30000"
/>