警告c3p0:发生了另一个错误:连接已关闭

时间:2017-03-29 22:13:39

标签: 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记录的警告消息,因为我们在结帐时测试连接,并且由于连接已关闭,它现在将从数据库获取新连接,应用程序将运行而没有任何问题?
  3. 任何帮助将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:3)

所以,这里没有足够的信息来说明问题的最初原因是什么。任何事情都可能发生,网络中断,无论如何。在结账时测试连接可确保Connection在结账时工作,但一旦在客户端,没有什么可以阻止中断。它应该是非常的,除非您长时间检查连接。 (不要这样做!使用连接池,采用及时,快速结账,即时登记策略。)

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

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

所有异常都会转发给应用程序。悄悄地吞下问题与c3p0的哲学正好相反。但无论您的应用程序使用此Connection执行什么操作都会触发异常,并且您的应用程序会继续执行其他触发更多操作的内容。

这并不一定意味着什么都不对。应用程序可以暂时将异常解释为连接失败以外的其他内容。可能由于违反约束而发生异常,如果是,则有解决方法?如果它是这样的,那么应用程序会在这里找到进一步的证据,是的,连接被破坏了,因为在处理完上一个异常之后,下一次使用Connection将继续失败。

如果我是你,我会审查触发此堆栈跟踪的应用程序代码,并特别注意可能过于宽容的先前步骤中的异常处理,这可能catch异常并在它应该反而中止。同样,情况不一定如此 - 可能是您的应用程序正在按照应有的方式执行,在适当的可恢复错误之后进行适当的重试或尝试继续运行,并且它非常强大对于重试失败的可能性,在这种情况下,当您已经检出连接失败时,您只会在日志中无害地看到这些堆栈跟踪,希望非常少。但是,在触发堆栈跟踪的步骤中,我肯定会在此代码路径中检查您的异常处理逻辑,重要的是在触发第一个异常的先前步骤中。通常一个Exception中止一个数据库代码路径(最终rollback()close()除外),这里你正在进行第二次,这可能很棒,但要确保它是你想做的

如果您经常看到这一点,请确保检查中的连接测试确实配置正确,然后尝试最小化检查连接的时间段,然后尝试理解为什么您的网络或服务器端的某些东西可能偶尔会失败。