这是环境:
- 在 Windows 上的 Tomcat 6.0.18 中运行的Java 5
- Web 应用程序(不确定版本)
- 数据库:SQL Server 2008 R2
- JDBC 驱动程序:jTDS 1.2.5
- 连接池提供程序:C3P0 0.9.1.2
我正在尝试调试客户遇到的问题。基本上每隔几周,我们的 Web 应用程序就会在他们的服务器上锁定,他们无法访问它。重新启动可以解决该问题。进一步的调查表明,所有内容都被锁定的原因是所有内容都在等待数据库连接返回。我认为问题可能出在 SQL Server,而不是 C3P0。
我相信发生的事情是 C3P0 的“空闲检查查询”挂起。查询是这样的:
select * from c3p0_connection_test_table
看起来这个查询已运行,但从未返回结果。这是我在线程转储中看到的内容。注意DefaultConnectionTester.activeCheckConnection(),这是空闲检查:
"com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2" daemon prio=6 tid=0x0000000007c32000 nid=0x1250 runnable [0x000000001072f000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.io.DataInputStream.readFully(DataInputStream.java:178)
at java.io.DataInputStream.readFully(DataInputStream.java:152)
at net.sourceforge.jtds.jdbc.SharedSocket.readPacket(SharedSocket.java:841)
at net.sourceforge.jtds.jdbc.SharedSocket.getNetPacket(SharedSocket.java:722)
- locked <0x000000016ac03f48> (a java.util.ArrayList)
at net.sourceforge.jtds.jdbc.ResponseStream.getPacket(ResponseStream.java:466)
at net.sourceforge.jtds.jdbc.ResponseStream.read(ResponseStream.java:103)
at net.sourceforge.jtds.jdbc.ResponseStream.peek(ResponseStream.java:88)
at net.sourceforge.jtds.jdbc.TdsCore.wait(TdsCore.java:3928)
at net.sourceforge.jtds.jdbc.TdsCore.executeSQL(TdsCore.java:1045)
- locked <0x000000016d965268> (a net.sourceforge.jtds.jdbc.TdsCore)
at net.sourceforge.jtds.jdbc.JtdsStatement.executeSQLQuery(JtdsStatement.java:465)
at net.sourceforge.jtds.jdbc.JtdsStatement.executeQuery(JtdsStatement.java:1301)
at com.mchange.v2.c3p0.impl.DefaultConnectionTester.activeCheckConnection(DefaultConnectionTester.java:73)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.testPooledConnection(C3P0PooledConnectionPool.java:374)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.refurbishIdleResource(C3P0PooledConnectionPool.java:310)
at com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask.run(BasicResourcePool.java:1999)
at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
但是什么会导致这样一个简单的查询在从套接字读取时挂起呢?我不相信该表上会有任何数据库锁定,因为它完全由 C3P0 管理并且从不插入/更新。另外,任何从池中获取连接的失败尝试(如果这是挂起的原因),我希望在某个地方有堆栈跟踪。相反,我看到的是应用程序只是锁定,因为所有未来的连接请求都在等待此“空闲检查”完成。
下面是等待“空闲检查”完成的线程之一:
"http-80-3" daemon prio=6 tid=0x0000000007c33800 nid=0x122c in Object.wait() [0x000000001082d000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:579)
- locked <0x0000000167a88a60> (a com.mchange.v2.resourcepool.BasicResourcePool)
at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:477)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:525)
at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128)
at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionProvider.java:81)
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446)
at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167)
at org.hibernate.jdbc.JDBCContext.connection(JDBCContext.java:142)
at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:85)
at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1354)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:555)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371)
at sun.reflect.GeneratedMethodAccessor105.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy15.getTransaction(Unknown Source)
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:317)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:105)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy79.getCrowdProperties(Unknown Source)
at com.jamasoftware.contour.gateway.crowd.CrowdSsoServices.autoLogin(Unknown Source)
at com.jamasoftware.contour.security.AutoLoginServicesManager.autoLogin(Unknown Source)
at org.springframework.security.ui.rememberme.RememberMeProcessingFilter.doFilterHttp(RememberMeProcessingFilter.java:74)
at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
at org.springframework.security.ui.AbstractProcessingFilter.doFilterHttp(AbstractProcessingFilter.java:277)
at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
at com.jamasoftware.contour.view.filter.CheckSetupFilter.doFilter(Unknown Source)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
at org.springframework.security.context.HttpSessionContextIntegrationFilter.doFilterHttp(HttpSessionContextIntegrationFilter.java:235)
at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
at org.springframework.security.concurrent.ConcurrentSessionFilter.doFilterHttp(ConcurrentSessionFilter.java:99)
at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
at com.jamasoftware.contour.view.filter.ExpirationFilter.doFilter(Unknown Source)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
at com.jamasoftware.contour.view.filter.GzipFilter.doFilter(Unknown Source)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
at org.springframework.security.util.FilterChainProxy.doFilter(FilterChainProxy.java:175)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:864)
at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:579)
at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1665)
at java.lang.Thread.run(Thread.java:619)
从C3P0的源代码来看,顶部的两行:
at java.lang.Object.wait(Native Method)
at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:579)
...仅在连接等待“空闲检查”时发生。
不幸的是,这是一个客户端,我无法在这里报告环境的具体细节。但我可以在下次通话时向他们提出任何建议。
更新:
他们的申请今天再次被锁定。以下是我们迄今为止尝试过的操作:
- 他们已更新到最新的 jTDS 驱动程序 (1.2.5)
- 我已将连接字符串上的
socketTimeout
属性设置为 300,但驱动程序仍然卡住5 分钟后,在 socketRead0() 上
- 我们将主动检查查询从“select * from c3p0_connection_test_table”更改为“select 1”,
- 我们添加了C3P0 的
unreturnedConnectionTimeout
和 debugUnreturnedConnectionStackTraces
属性(不过,这些属性不会捕获断开的连接)
以下是我们设置的所有 C3P0 连接属性:
<property name="minPoolSize" value="1"/>
<property name="maxPoolSize" value="30"/>
<property name="acquireIncrement" value="3"/>
<property name="automaticTestTable" value="c3p0_connection_test_table"/>
<property name="idleConnectionTestPeriod" value="30"/>
<property name="testConnectionOnCheckin" value="true"/>
<property name="testConnectionOnCheckout" value="true"/>
发生的一件奇怪的事情是,虽然应用程序被锁定,我们尝试使用应用程序用户登录 SQL Server Management Studio,但它不让我们进入(我认为这只是正常的超时错误)。数据库已启动并侦听端口 1433(使用 telnet 验证),因此我认为这意味着已达到数据库的最大连接数。不过,我不确定这是否有助于确定此问题的原因。
跟踪线索但没有成功:
- 此人 存在操作系统问题,以及服务器上可能存在的 NIC 卡数量问题
- 下面的回答者向我指出了旧版本中的一个错误总溶解固体此处
有用的答案可以让我检查客户计算机上的某些内容,或者指出可能的根本原因。任何能帮助我查明真相的答案都将获得赏金。
Here is the environment:
- Java 5
- Web application running in Tomcat 6.0.18 on Windows (not sure the version)
- Database: SQL Server 2008 R2
- JDBC Driver: jTDS 1.2.5
- Connection pool provider: C3P0 0.9.1.2
I am trying to debug a problem that a client is having. Basically every couple weeks, our web application locks up on their server, and they can't access it. A restart fixes the issue. Further investigation shows that the reason everything is locked up is that everything is waiting on the database connections to return. I think the issue is likely with SQL Server, not C3P0.
What I believe is going on is that C3P0's "idle check query" is hanging. The query is this:
select * from c3p0_connection_test_table
It looks like this query is run, and the result is never returned. Here is what I see in my thread dump. Notice DefaultConnectionTester.activeCheckConnection()
, which is the idle check:
"com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2" daemon prio=6 tid=0x0000000007c32000 nid=0x1250 runnable [0x000000001072f000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.io.DataInputStream.readFully(DataInputStream.java:178)
at java.io.DataInputStream.readFully(DataInputStream.java:152)
at net.sourceforge.jtds.jdbc.SharedSocket.readPacket(SharedSocket.java:841)
at net.sourceforge.jtds.jdbc.SharedSocket.getNetPacket(SharedSocket.java:722)
- locked <0x000000016ac03f48> (a java.util.ArrayList)
at net.sourceforge.jtds.jdbc.ResponseStream.getPacket(ResponseStream.java:466)
at net.sourceforge.jtds.jdbc.ResponseStream.read(ResponseStream.java:103)
at net.sourceforge.jtds.jdbc.ResponseStream.peek(ResponseStream.java:88)
at net.sourceforge.jtds.jdbc.TdsCore.wait(TdsCore.java:3928)
at net.sourceforge.jtds.jdbc.TdsCore.executeSQL(TdsCore.java:1045)
- locked <0x000000016d965268> (a net.sourceforge.jtds.jdbc.TdsCore)
at net.sourceforge.jtds.jdbc.JtdsStatement.executeSQLQuery(JtdsStatement.java:465)
at net.sourceforge.jtds.jdbc.JtdsStatement.executeQuery(JtdsStatement.java:1301)
at com.mchange.v2.c3p0.impl.DefaultConnectionTester.activeCheckConnection(DefaultConnectionTester.java:73)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.testPooledConnection(C3P0PooledConnectionPool.java:374)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.refurbishIdleResource(C3P0PooledConnectionPool.java:310)
at com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask.run(BasicResourcePool.java:1999)
at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
But what could cause such a simple query to hang at reading from the socket? I don't believe there would be any database locking on this table, as it is completely managed by C3P0 and never inserted/updated. Also, any failed attempts to get connections from the pool (if this were the cause of the hanging), I would expect a stacktrace somewhere. Instead what I see is the app just locking up, because all future connection requests are waiting for this "idle check" to complete.
Here is one of the threads that is waiting for the "idle check" to complete:
"http-80-3" daemon prio=6 tid=0x0000000007c33800 nid=0x122c in Object.wait() [0x000000001082d000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:579)
- locked <0x0000000167a88a60> (a com.mchange.v2.resourcepool.BasicResourcePool)
at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:477)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:525)
at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128)
at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionProvider.java:81)
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446)
at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167)
at org.hibernate.jdbc.JDBCContext.connection(JDBCContext.java:142)
at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:85)
at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1354)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:555)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371)
at sun.reflect.GeneratedMethodAccessor105.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy15.getTransaction(Unknown Source)
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:317)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:105)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy79.getCrowdProperties(Unknown Source)
at com.jamasoftware.contour.gateway.crowd.CrowdSsoServices.autoLogin(Unknown Source)
at com.jamasoftware.contour.security.AutoLoginServicesManager.autoLogin(Unknown Source)
at org.springframework.security.ui.rememberme.RememberMeProcessingFilter.doFilterHttp(RememberMeProcessingFilter.java:74)
at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
at org.springframework.security.ui.AbstractProcessingFilter.doFilterHttp(AbstractProcessingFilter.java:277)
at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
at com.jamasoftware.contour.view.filter.CheckSetupFilter.doFilter(Unknown Source)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
at org.springframework.security.context.HttpSessionContextIntegrationFilter.doFilterHttp(HttpSessionContextIntegrationFilter.java:235)
at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
at org.springframework.security.concurrent.ConcurrentSessionFilter.doFilterHttp(ConcurrentSessionFilter.java:99)
at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
at com.jamasoftware.contour.view.filter.ExpirationFilter.doFilter(Unknown Source)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
at com.jamasoftware.contour.view.filter.GzipFilter.doFilter(Unknown Source)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
at org.springframework.security.util.FilterChainProxy.doFilter(FilterChainProxy.java:175)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:864)
at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:579)
at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1665)
at java.lang.Thread.run(Thread.java:619)
From looking at C3P0's source code, the two lines at the top:
at java.lang.Object.wait(Native Method)
at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:579)
... only happen when the connection is waiting for the "idle check".
Unfortunately, this is a client, and I can't report the exact details of the environment here. But any suggestions I can take to them on our next call.
UPDATE:
Their application was locked up again today. Here are the things that we've tried so far:
- They have updated to the latest jTDS driver (1.2.5)
- I have set the
socketTimeout
property on the connection string to 300 but still the driver stays stuck on socketRead0() long after 5 minutes
- We changed the active check query from "select * from c3p0_connection_test_table" to "select 1"
- We have added the
unreturnedConnectionTimeout
and debugUnreturnedConnectionStackTraces
properties to C3P0 (these aren't catching broken connections, though)
Here are all the C3P0 connection properties we have set:
<property name="minPoolSize" value="1"/>
<property name="maxPoolSize" value="30"/>
<property name="acquireIncrement" value="3"/>
<property name="automaticTestTable" value="c3p0_connection_test_table"/>
<property name="idleConnectionTestPeriod" value="30"/>
<property name="testConnectionOnCheckin" value="true"/>
<property name="testConnectionOnCheckout" value="true"/>
One weird thing that happened was that while the application was locked up, we tried to log into SQL Server Management Studio with the application user, and it wouldn't let us in (I think it was just a normal timeout error). The database was started and listening on port 1433 (verified with telnet
), so I think that means that the maximum number of connections to the database had been reached. I'm not sure if that helps determine the cause of this issue, though.
Leads followed without success:
- This person had an issue with operating systems, and potentially the number of NIC cards on the server
- An answerer below pointed me to a bug in an older version of jTDS here
Helpful answers can either ask me to check on something on the client's machine, or point me to a possible root cause. Whatever answers helps me track this down will get the bounty.
发布评论
评论(4)
第一个想法:检查他们正在使用最新的 jTDS 版本,并且 SQL Server 是否已修补并更新到最新的 SP!
jTDS 错误跟踪中有一些关于此类行为的报告,最值得注意的是 这个。显然 SQL Server 正在关闭连接,但 jTDS 没有注意到。
在较新版本的 jTDS 中,有一个
socketTimeout
属性(默认=0 ),也许这有帮助。您还可以测试不同的 JDBC 驱动程序。
First ideas: check they're using the latest jTDS version and SQL Server is patched and updated to latest SP!
There are some reports about this kind of behaviour in jTDS bug tracking, most notably this one. Apparently the SQL Server is closing the connection but jTDS doesn't notice.
In newer versions of jTDS there is a
socketTimeout
property (default=0), maybe this helps.You could also test a different JDBC driver.
在sql server中检查是否禁用-属性-连接-“使用查询调控器防止长时间运行的查询”
In sql server check if - properties - connections - ”Use query governor to prevent long-running queries” is disabled
使用 jtds 连接到 sql server 时,我遇到了 c3p0 (0.9.1) 挂起的类似问题。
我通过不使用 c3p0 并在需要时使用 DriverManager 打开连接来解决这个问题。我确信它的性能不那么好,但它确实有效。
I ran into a similar issue with c3p0 (0.9.1) hanging when connecting to sql server using jtds.
I solved it by not using c3p0 and just opening a connection whenever I needed one using DriverManager. I'm sure it is not as performant, but it works.
在测试连接时是否还有另一个线程关闭连接?看起来 C3P0 在 c3p0-0.9.2-pre3 中修复了这个问题:
来自: https://github.com/swaldman/c3p0/blob /master/src/dist-static/CHANGELOG
Was there also another thread closing a connection while the connection was being tested? Looks like C3P0 fixed this in c3p0-0.9.2-pre3:
from: https://github.com/swaldman/c3p0/blob/master/src/dist-static/CHANGELOG