我简化了以下代码:
Connection conn = dataSource.getConnection();
UserTransaction ut = util.getTransaction();
// ut.begin();
for (xxx) { // heavy for-loop, a lot of records
ut.begin();
PreparedStatement pstmt = conn.prepareStatement(sql); // very fast sql update
pstmt.executeUpdate();
pstmt.close();
ut.commit();
}
//ut.commit();
如上面的代码所示,for-loop
将运行很长时间,大约1-2小时。
上次,当我将begin
和commit
放在for-loop
之外时,我在循环结束时遇到错误:
java.sql.SQLRecoverableException: IO Error: Connection timed out
at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:1065)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1329)
然后我意识到,系统无法提交,因为在这种情况下,UserTransaction
可能已经超时。 (错误抛出ut.commit()
)
所以我将begin
和commit
移到了for-loop
以避免这个问题,但我在1小时左右的某个地方又出现了另一个错误:
java.sql.SQLException: Connection has already been closed.
at weblogic.jdbc.wrapper.PoolConnection.checkConnection(PoolConnection.java:62)
at weblogic.jdbc.wrapper.Connection.preInvocationHandler(Connection.java:100)
at weblogic.jdbc.wrapper.Connection.prepareStatement(Connection.java:553)
我的代码是单线程的,所以我非常确定,没有其他线程可以关闭conn
连接。 (这次错误抛出conn.prepareStatement(sql)
)
由于for-loop
,连接不是空闲的,因为它一直在执行update
和commit
。如何自动关闭连接(由于任何原因?超时?)?
那么连接会发生什么?我搜索但无法找到任何超时设置,如连接的池借用超时或等等等等。
有人有想法吗?