java - 警告 c3p0 : Another error has occurred: Connection is Closed

标签 java sql-server c3p0

我们在 Microsoft SQL 数据库应用程序中使用 c3p0 作为连接池。连接在结帐时使用验证查询进行测试,以便应用程序无法使用过时的连接。

最近,我们开始在应用程序日志中看到以下警告(其中许多消息按顺序出现)。有人见过这种异常吗?这是什么意思?

2017-03-29 09:34:24 [WARNING] [c3p0] A PooledConnection that has already signalled a Connection error is still in use!
2017-03-29 09:34:24 [WARNING] [c3p0] Another error has occurred [ com.microsoft.sqlserver.jdbc.SQLServerException: The connection is closed. ] which will not be reported to listeners!
2017-03-29 09:34:24 com.microsoft.sqlserver.jdbc.SQLServerException: The connection is closed.
2017-03-29 09:34:24     at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:190)
2017-03-29 09:34:24     at com.microsoft.sqlserver.jdbc.SQLServerConnection.checkClosed(SQLServerConnection.java:388)
2017-03-29 09:34:24     at com.microsoft.sqlserver.jdbc.SQLServerConnection.prepareStatement(SQLServerConnection.java:2166)
2017-03-29 09:34:24     at com.microsoft.sqlserver.jdbc.SQLServerConnection.prepareStatement(SQLServerConnection.java:1853)
2017-03-29 09:34:24     at com.mchange.v2.c3p0.impl.NewProxyConnection.prepareStatement(NewProxyConnection.java:1076)

我担心的是:

  1. 此警告(或异常消息)是否意味着查询实际上未能执行并且代码将引发异常?
  2. 这是否只是 c3p0 记录的一条警告消息,因为我们在结账时测试连接,并且由于连接已关闭,它现在将从数据库获取新连接,并且应用程序将运行而不会出现任何问题?

任何帮助将不胜感激。谢谢!

最佳答案

因此,这里没有足够的信息来说明问题的最初原因是什么。任何事情都可能发生,网络中断等等。在结帐时测试连接可确保连接在结帐时正常工作,但一旦进入客户端,就无法阻止中断。它应该是非常多的,除非您长时间保持连接检查。 (不要这样做!使用连接池,采用及时、快速 checkout 、立即 checkin 策略。)

无论如何,应用程序使用连接的某些尝试引发了异常。然后,c3p0 在内部检查连接,确定连接已损坏,并发出一个事件(由 JDBC 规范指定,但仅内部监听器感兴趣),指示连接错误。 c3p0 通过将连接标记为销毁而不是在应用程序完成时 checkin 来对此做出响应。

尽管应用程序出现了第一个异常,但仍继续使用连接。发生了第二个异常(是的,这个连接确实被破坏了)。这就是 c3p0 在这里记录的内容。它忽略第二个异常,而不是发出连接错误信号,因为已经为此连接发出了连接错误信号。但有点惊讶和恼火地发现Connection还在使用;)

所有异常都会转发到应用程序。默默地吞掉问题与 c3p0 的理念恰恰相反。但是,无论您的应用程序对此连接执行什么操作,都会触发异常,并且您的应用程序会继续执行其他操作,从而触发更多异常。

这并不一定意味着有什么问题。应用程序可能会尝试将异常解释为连接失败以外的情况。也许由于违反约束而发生异常,如果是这样,有解决方法吗?如果是类似的情况,应用程序会在这里找到进一步的证据,证明连接已损坏,因为在处理了上一个异常之后,下一次使用连接将继续失败。

如果我是你,我会检查触发此堆栈跟踪的应用程序代码,并特别查找先前步骤中可能过于宽容的异常处理,这可能 catch异常并在应该中止时继续。同样,情况不一定如此——可能您的应用程序正在执行其应该执行的操作,它正在适本地重试或在出现潜在可恢复错误后尝试继续,并且它对于重试也失败的可能性具有鲁棒性,其中当已经 checkout 的连接失败时,您只会在日志中无害地看到这些堆栈跟踪,希望很少见。但我肯定会在触发堆栈跟踪的步骤期间,以及重要的是在触发第一个异常的先前步骤期间,检查此代码路径中的异常处理逻辑。通常,一个异常会中止数据库代码路径(最终的 rollback()close() 除外),在这里您将继续进行第二个异常,这可能很棒,但请确保这是您想要做的。

如果您经常看到这种情况,请确保结帐时的连接测试确实配置正确,然后尝试最大程度地缩短结帐连接的时间,然后尝试了解为什么您的网络或服务器端的某些内容可能会偶尔会失败。

关于java - 警告 c3p0 : Another error has occurred: Connection is Closed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43105118/

相关文章:

sql - 使用 vb.net 将表脚本编写为 CREATE TO

mysql - C3P0 明显死锁

java - 如果服务器崩溃,如何以及何时从 RMI 注册表中删除名称?

java - 将函数传递给 JavaPairRDD<K,V> 中的 KEY

java - 为什么 Collections.shuffle(List) 之后会出现空行?

java - jenkins(java) 和 Bitbucket 插件之间的 SSL 错误

SQL MAX() 函数返回所有结果

mysql - 如何使用其他参数进行 SQL INSERT CROSS JOIN

java - c3p0-0.9.5.2 语句展开导致抽象方法错误

spring - 共享的 C3P0 JNDI 数据源在 Jetty 的 servlet 取消部署期间关闭,其他 servlet 不再可以访问