如何让Squeryl释放关闭的连接回C3P0?

时间:2013-08-21 21:16:17

标签: scala c3p0 squeryl

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

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释放这个与池的连接并获得一个新的连接?

1 个答案:

答案 0 :(得分:1)

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

对于其他人看到相同的错误,我也发现你可以得到c3p0错误(上面问题文本中的前两个错误),即使没有任何错误。如果持有数据库连接的线程忙(我的情况下是Thread.sleep(),用于测试)和c3p0注意事项,那么连接已经失效,那么你可以得到关于仍然正在使用的死连接的错误。在这种情况下,这是一个完全正常的情况,只是一个问题,哪个线程首先看到问题 - 没什么可担心的。