1

有时我会在日志中反复看到以下错误:

com.mchange.v2.c3p0.impl.NewPooledConnection - [c3p0] A PooledConnection that has already signalled a Connection error is still in use!
com.mchange.v2.c3p0.impl.NewPooledConnection - [c3p0] Another error has occurred [ org.postgresql.util.PSQLException: This connection has been closed. ] which will not be reported to listeners!
org.postgresql.util.PSQLException: This connection has been closed.
        at org.postgresql.jdbc2.AbstractJdbc2Connection.checkClosed(AbstractJdbc2Connection.java:822)
        at org.postgresql.jdbc2.AbstractJdbc2Connection.rollback(AbstractJdbc2Connection.java:839)
        at com.mchange.v2.c3p0.impl.NewProxyConnection.rollback(NewProxyConnection.java:855)
        at org.squeryl.dsl.QueryDsl$class._executeTransactionWithin(QueryDsl.scala:131)
        at org.squeryl.dsl.QueryDsl$class.transaction(QueryDsl.scala:78)
        at org.squeryl.PrimitiveTypeMode$.transaction(PrimitiveTypeMode.scala:40)

下面是我自己的代码到我的transaction {}块为止的跟踪。

transaction {}我的软件在引发异常后重复,但它似乎再次使用相同的(关闭的)连接,因此下一次尝试也失败了。奇怪的是,这需要相当长的时间,有时 50 秒,有时长达 2 分钟。人们会认为关闭的连接会立即失败。

如何让 Squeryl 释放与池的连接并获取新连接?

4

1 回答 1

1

我发现了为什么会这样。我需要使用 Squeryl 不支持的 JDBC 功能。所以我从 Squeryl 获得了连接并直接使用它。但是我有一个错误,即准备好的语句没有被关闭。这导致死连接被一遍又一遍地重用。我不确定这是如何发生或为什么发生的。但是,一旦我将语句的结束放在 finally 块中,一切都开始工作了。现在,当 Squeryl 第二次到达事务块时,它会收到来自 c3p0 的新连接。

对于其他看到相同错误的人,我还发现即使没有任何问题,您也可以得到 c3p0 错误(上面问题文本中的前两个错误)。如果您持有数据库连接的线程很忙(在我的情况下是一个 Thread.sleep() 用于测试)并且 c3p0 在您执行此操作之前通知该连接已死,那么您可能会收到有关死连接仍在使用中的错误。在这种情况下,这是一个完全正常的情况,只是哪个线程首先看到问题的问题——没什么好担心的。

于 2013-08-26T22:01:44.913 回答