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

Java 警告c3p0:发生了另一个错误:连接已关闭,java,sql-server,c3p0,Java,Sql Server,C3p0,我们使用c3p0作为Microsoft SQL数据库应用程序中的连接池。通过验证查询在签出时对连接进行测试,这样应用程序就不会使用过时的连接 最近,我们开始在应用程序日志中看到以下警告(这些消息中有很多是按顺序出现的)。有人见过这种例外情况,这意味着什么 2017-03-29 09:34:24 [WARNING] [c3p0] A PooledConnection that has already signalled a Connection error is still in use! 201

我们使用c3p0作为Microsoft SQL数据库应用程序中的连接池。通过验证查询在签出时对连接进行测试,这样应用程序就不会使用过时的连接

最近,我们开始在应用程序日志中看到以下警告(这些消息中有很多是按顺序出现的)。有人见过这种例外情况,这意味着什么

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)
我关注的是:

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

  • 任何帮助都将不胜感激。谢谢

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

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

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

    所有异常都会中继到应用程序。默默地接受问题与c3p0的哲学截然相反。但是,无论您的应用程序使用此连接执行什么操作,都会触发一个异常,并且您的应用程序会继续执行其他操作,从而触发更多异常

    这并不一定意味着任何事情都是错的。应用程序可能会暂时将异常解释为连接失败以外的情况。可能由于违反约束而发生异常,如果是,是否有解决方法?如果是这样的话,应用程序将在这里找到进一步的证据,证明连接断开了,因为在处理了以前的异常之后,连接的下一次使用将继续失败

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


    如果您经常看到这种情况,请确保签出时的连接测试配置正确,然后尽量缩短签出连接的时间,然后尝试了解您的网络或服务器端的某些东西偶尔会出现故障的原因。

    ,这里没有足够的信息来说明问题的最初原因。任何事情都有可能发生,网络中断等等。在签出时测试连接可以确保连接在签出时正常工作,但一旦进入客户端,就没有任何东西可以阻止中断。这应该是非常重要的,除非你保持连接检查了很长一段时间。(不要这样做!使用连接池,采用及时、快速签出、立即签入的策略。)

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

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

    所有异常都会中继到应用程序。默默地接受问题与c3p0的哲学截然相反。但是无论您的应用程序对这个连接做了什么,都会触发一个异常,并且