【发布时间】:2014-09-12 14:54:20
【问题描述】:
我已将 Tomcat 配置为使用 ComboPooledDataSource,方法是在我的 context.xml 中添加以下内容。
<Resource
name="jdbc/abcdatasource"
auth="Container"
type="com.mchange.v2.c3p0.ComboPooledDataSource"
factory="org.apache.naming.factory.BeanFactory"
maxPoolSize="20"
minPoolSize="5"
maxIdleTime="3000"
acquireIncrement="1"
user="abc"
password="pw_here"
driverClass="oracle.jdbc.driver.OracleDriver"
jdbcUrl="jdbc:oracle:thin:@abc.def.ghi.net:1521:BLAH"
/>
我想按照 maxPoolSize 中的定义将 db 连接数限制为 20,但我的打开连接数超过了这个数。例如,昨天,我有 35 个打开的连接。我的日志正在捕获以下内容。
2014-09-11 00:37:47,077 INFO [com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2] NewPooledConnection:725 - - [c3p0] Exceptions occurred while trying to close a PooledConnection's resources normally.
2014-09-11 00:37:47,077 INFO [com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2] NewPooledConnection:735 - - [c3p0] NewPooledConnection close Exception.
java.sql.SQLException: Io exception: Connection timed out
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:255)
at oracle.jdbc.driver.T4CConnection.logoff(T4CConnection.java:481)
at oracle.jdbc.driver.PhysicalConnection.close(PhysicalConnection.java:1203)
at com.mchange.v2.c3p0.impl.NewPooledConnection.close(NewPooledConnection.java:549)
at com.mchange.v2.c3p0.impl.NewPooledConnection.close(NewPooledConnection.java:234)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.destroyResource(C3P0PooledConnectionPool.java:470)
at com.mchange.v2.resourcepool.BasicResourcePool$1DestroyResourceTask.run(BasicResourcePool.java:964)
at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
2014-09-11 00:37:47,078 WARN [com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2] BasicResourcePool:972 - - Failed to destroy resource: com.mchange.v2.c3p0.impl.NewPooledConnection@3ca5d95d
java.sql.SQLException: Some resources failed to close properly while closing com.mchange.v2.c3p0.impl.NewPooledConnection@3ca5d95d
at com.mchange.v2.c3p0.impl.NewPooledConnection.close(NewPooledConnection.java:571)
at com.mchange.v2.c3p0.impl.NewPooledConnection.close(NewPooledConnection.java:234)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.destroyResource(C3P0PooledConnectionPool.java:470)
at com.mchange.v2.resourcepool.BasicResourcePool$1DestroyResourceTask.run(BasicResourcePool.java:964)
at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
鉴于此信息,我的打开连接数超过我的 maxPoolSize 的可能原因是什么?
我知道有相关的 stackoverflow 线程,例如 here 和 here,,但不清楚我的情况可能是什么问题。在这些类似的线程中,有多个连接池 - 但当我将 Web 应用程序容器配置为使用 c3p0 ComboPooledDataSource 时,我希望有一个不同的连接池。也许我在那里遗漏了一些东西......
任何帮助将不胜感激!!!!!!
编辑 1:对于一些额外的上下文,这不是一个新的应用程序。它已经运行多年。然而,新的是将 Tomcat 与 c3p0 数据源一起使用。从 WebLogic 转换到 Tomcat 后出现此问题。
编辑 2:当我最初创建这篇文章时,我未能提供可能非常有用的日志信息。在 log4j 中捕获的 DEADLOCK 问题如下所示。自从我注意到这个问题以来,我一直在密切监视连接,并且连接增加似乎与死锁问题有关。如果我不得不猜测,我会说它在死锁之后创建了一个新的连接池。
2014-09-11 11:36:45,320 WARN [Timer-0] ThreadPoolAsynchronousRunner:608 - - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@1c203f2b -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
2014-09-11 11:36:45,323 WARN [Timer-0] ThreadPoolAsynchronousRunner:624 - - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@1c203f2b -- APPARENT DEADLOCK!!! Complete Status:
Managed Threads: 3
Active Threads: 3
Active Tasks:
com.mchange.v2.resourcepool.BasicResourcePool$1DestroyResourceTask@4a50503d (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2)
com.mchange.v2.resourcepool.BasicResourcePool$1DestroyResourceTask@5ec3fae8 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0)
com.mchange.v2.resourcepool.BasicResourcePool$1DestroyResourceTask@148dc5f3 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1)
Pending Tasks:
com.mchange.v2.resourcepool.BasicResourcePool$1DestroyResourceTask@67bedf0f
com.mchange.v2.resourcepool.BasicResourcePool$1DestroyResourceTask@242686ff
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@5d68e1e3
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@10c62dfe
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@42f5874c
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@585b0ec
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@c2258c9
Pool thread stack traces:
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2,5,main]
java.net.SocketInputStream.socketRead0(Native Method)
java.net.SocketInputStream.read(SocketInputStream.java:129)
oracle.net.ns.Packet.receive(Unknown Source)
oracle.net.ns.DataPacket.receive(Unknown Source)
oracle.net.ns.NetInputStream.getNextPacket(Unknown Source)
oracle.net.ns.NetInputStream.read(Unknown Source)
oracle.net.ns.NetInputStream.read(Unknown Source)
oracle.net.ns.NetInputStream.read(Unknown Source)
oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:1104)
oracle.jdbc.driver.T4CMAREngine.unmarshalSB1(T4CMAREngine.java:1075)
oracle.jdbc.driver.T4C7Ocommoncall.receive(T4C7Ocommoncall.java:106)
oracle.jdbc.driver.T4CConnection.logoff(T4CConnection.java:465)
oracle.jdbc.driver.PhysicalConnection.close(PhysicalConnection.java:1203)
com.mchange.v2.c3p0.impl.NewPooledConnection.close(NewPooledConnection.java:549)
com.mchange.v2.c3p0.impl.NewPooledConnection.close(NewPooledConnection.java:234)
com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.destroyResource(C3P0PooledConnectionPool.java:470)
com.mchange.v2.resourcepool.BasicResourcePool$1DestroyResourceTask.run(BasicResourcePool.java:964)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0,5,main]
java.net.SocketInputStream.socketRead0(Native Method)
java.net.SocketInputStream.read(SocketInputStream.java:129)
oracle.net.ns.Packet.receive(Unknown Source)
oracle.net.ns.DataPacket.receive(Unknown Source)
oracle.net.ns.NetInputStream.getNextPacket(Unknown Source)
oracle.net.ns.NetInputStream.read(Unknown Source)
oracle.net.ns.NetInputStream.read(Unknown Source)
oracle.net.ns.NetInputStream.read(Unknown Source)
oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:1104)
oracle.jdbc.driver.T4CMAREngine.unmarshalSB1(T4CMAREngine.java:1075)
oracle.jdbc.driver.T4C7Ocommoncall.receive(T4C7Ocommoncall.java:106)
oracle.jdbc.driver.T4CConnection.logoff(T4CConnection.java:465)
oracle.jdbc.driver.PhysicalConnection.close(PhysicalConnection.java:1203)
com.mchange.v2.c3p0.impl.NewPooledConnection.close(NewPooledConnection.java:549)
com.mchange.v2.c3p0.impl.NewPooledConnection.close(NewPooledConnection.java:234)
com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.destroyResource(C3P0PooledConnectionPool.java:470)
com.mchange.v2.resourcepool.BasicResourcePool$1DestroyResourceTask.run(BasicResourcePool.java:964)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1,5,main]
java.net.SocketInputStream.socketRead0(Native Method)
java.net.SocketInputStream.read(SocketInputStream.java:129)
oracle.net.ns.Packet.receive(Unknown Source)
oracle.net.ns.DataPacket.receive(Unknown Source)
oracle.net.ns.NetInputStream.getNextPacket(Unknown Source)
oracle.net.ns.NetInputStream.read(Unknown Source)
oracle.net.ns.NetInputStream.read(Unknown Source)
oracle.net.ns.NetInputStream.read(Unknown Source)
oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:1104)
oracle.jdbc.driver.T4CMAREngine.unmarshalSB1(T4CMAREngine.java:1075)
oracle.jdbc.driver.T4C7Ocommoncall.receive(T4C7Ocommoncall.java:106)
oracle.jdbc.driver.T4CConnection.logoff(T4CConnection.java:465)
oracle.jdbc.driver.PhysicalConnection.close(PhysicalConnection.java:1203)
com.mchange.v2.c3p0.impl.NewPooledConnection.close(NewPooledConnection.java:549)
com.mchange.v2.c3p0.impl.NewPooledConnection.close(NewPooledConnection.java:234)
com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.destroyResource(C3P0PooledConnectionPool.java:470)
com.mchange.v2.resourcepool.BasicResourcePool$1DestroyResourceTask.run(BasicResourcePool.java:964)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
正在使用的c3p0版本是0.9.1.2
【问题讨论】:
-
几个问题:您如何测量打开的连接(在数据库中或仅在 Java 代码中打印连接对象)?你是如何从代码中获取连接的? getConnection() 还是 getConnection(username,password)?从您的异常跟踪中,看起来连接没有关闭。你能从数据库的角度找出原因吗?
-
首先,从我正在运行 tomcat 的服务器上,我使用命令 # netstat -an | 测量打开的连接。 grep 1521。我们的 DBA 还仅从数据库的角度检查了打开的连接,这与我所看到的一致。
-
关于获取连接的方法,我可以深入研究,但我的印象是即使使用getConnection(username,password)方法,也不会创建更多不是一个连接池,因为我在 context.xml 中配置了一个用户名和密码。
-
如果我们使用不同的用户名会这样。但我在想
close()通话期间的错误。你能调试你的方法来捕捉超时的根本原因吗?
标签: java tomcat datasource connection-pooling c3p0