2011-07-22 242 views
27

java.sql.SQLException的原因:与Oracle关闭的连接?Oracle数据库:java.sql.SQLException:关闭连接

java.sql.SQLException中:在oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)关闭连接 在oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146) at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:208) at oracle.jdbc.driver.PhysicalConnection.commit(PhysicalConnection.java:1131) at oracle.jdbc.OracleConnectionWrapper.commit(OracleConnectionWrapper.java: 117)

我们从失败中得到这个错误o ver数据库连接。我们也为其他数据库使用相同的代码。但只有一个数据库可以看到这个问题。这是因为连接可能由于长时间不活动而超时,我们正试图使用​​它?请让我知道如果你需要更多的细节......

AbandonedConnectionTimeout设置为15分钟 InactivityTimeout设置为30分钟

回答

32

这意味着连接成功在某种程度上成立,但是当你试图提交正确的有,连接不再打开。你提到的参数听起来像连接池设置。如果是这样,他们与这个问题无关。最可能的原因是您和数据库之间的防火墙会在一定的空闲时间后终止连接。最常见的修复方法是在连接被检出时使连接池运行验证查询。这将立即识别并驱逐死亡连接,确保您只能从游泳池中获得良好的连接。

+0

感谢您的回答。验证连接属性是否会增加任何开销?我只看到这个数据库中的一个,我也怀疑这个数据库DB有问题。 –

+4

它自然会增加一些开销,因为它必须实际地击中数据库才能验证连接;然而,每个数据库都有一个推荐的“验证查询”,因此在数据库方面的开销最小,因此,您将得到的唯一减速是来自任何网络延迟。无论问题出在哪里,添加验证查询都是避免从池中死去的连接的一种非常简单的方法。我相信目前对Oracle推荐的查询是'从双选择1' –

8

您必须验证连接。

如果您使用Oracle,您可能会使用Oracle的Universal Connection Pool。以下假设你这样做。

验证连接的最简单方法是告诉Oracle连接在借用时必须经过验证。这可以通过

pool.setValidateConnectionOnBorrow(true); 

但它只适用于持有短时间的连接。如果您长时间借用连接,连接可能会在您拿着连接时断开。在这种情况下,你必须与

if (connection == null || !((ValidConnection) connection).isValid()) 

进一步的详情请参见Oracle documentation明确验证连接。

+0

如果您不能使用UCP或不想处理公共Maven存储库中不存在的Oracle工件令人头疼的问题,我最近才发现java.sql.Connection有一个isValid方法。它在超时工作。 – obesechicken13

+0

和oracle.ucp.jdbc。ValidConnection的isValid导致我的预定记录器在java.lang.ClassCastException中崩溃 – obesechicken13