如何让Squeryl将闭合连接释放回C3P0



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

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将此连接释放到池并获取新连接?

我发现了发生这种情况的原因。我需要使用Squeryl不支持的JDBC功能。所以我从Squeryl那里得到了连接,并直接使用了它。但我遇到了一个错误,一个准备好的语句没有被关闭。这导致死连接被反复使用。我不知道这是怎么发生的,也不知道为什么会发生。但当我把声明的结尾放在一个最终的块中时,一切都开始工作了。现在,当Squeryl第二次到达事务块时,它接收到来自c3p0的新连接。

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

最新更新