这是我执行更新查询的代码
public boolean executeQuery(Connection con,String query) throws SQLException
{
boolean flag=false;
try
{
Statement st = con.createStatement();
flag=st.execute(query);
st.close();
st=null;
flag=true;
}
catch (Exception e)
{
flag=false;
e.printStackTrace();
throw new SQLException(" UNABLE TO FETCH INSERT");
}
return flag;
}
最大打开光标设置为4000
代码正在执行
update tableA set colA ='x',lst_upd_date = trunc(sysdate) where trunc(date) = to_date('"+date+"','dd-mm-yyyy')
更新查询大约8000次
但是在大约2000天之后它的抛出异常为“最大开放游标超过”
请为此建议代码更改。 @TimBiegeleisen这里是代码get connecttion
public Connection getConnection(String sessId)
{
Connection connection=null;
setLastAccessed(System.currentTimeMillis());
connection=(Connection)sessionCon.get(sessId);
try
{
if(connection==null || connection.isClosed() )
{
if ( ds == null )
{
InitialContext ic = new InitialContext();
ds = (DataSource) ic.lookup("java:comp/env/iislDB");
}
connection=ds.getConnection();
sessionCon.put(sessId, connection);
}
}
catch (SQLException e)
{
e.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
}
return connection;
}
`
错误堆栈如下所示
java.sql.SQLException: ORA-01000: maximum open cursors exceeded
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:180)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:208)
at oracle.jdbc.ttc7.Oopen.receive(Oopen.java:118)
at oracle.jdbc.ttc7.TTC7Protocol.open(TTC7Protocol.java:472)
at oracle.jdbc.driver.OracleStatement.<init>(OracleStatement.java:499)
at oracle.jdbc.driver.OracleConnection.privateCreateStatement(OracleConnection.java:683)
at oracle.jdbc.driver.OracleConnection.createStatement(OracleConnection.java:560)
at org.apache.tomcat.dbcp.dbcp.DelegatingConnection.createStatement(DelegatingConnection.java:257)
at org.apache.tomcat.dbcp.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.createStatement(PoolingDataSource.java:216)
at com.iisl.business.adminbo.computeindex.MoviIndexComputeBO.calculateMoviValue(MoviIndexComputeBO.java:230)
答案 0 :(得分:1)
最快的解决方案之一是通过在SQL提示符上发出以下命令来增加每个连接可以处理的游标:
alter system set open_cursors = 1000
此外,在代码中添加finally块并关闭连接以帮助在异常发生时关闭游标。
此外,运行此查询以查看实际光标的打开位置。
select sid ,sql_text, count(*) as "OPEN CURSORS", USER_NAME from v$open_cursor
finally {
if (connection!=null) {
connection.close();
}
答案 1 :(得分:1)
您的代码有光标泄漏。这是造成错误的原因。在遇到错误之前,您的代码似乎不太可能在2000天(大约5。5年)内完成。如果是这种情况,我敢打赌,你十分乐意在十年内重启服务器两次。
在try
区块中,您可以创建Statement
。如果在创建语句的时间和调用st.close()
的时间之间抛出异常,则代码将使语句保持打开状态,并且您将泄漏游标。一旦会话泄露了4000个游标,您就会收到错误。增加max_open_cursors
只会在错误发生时延迟,它不会解决根本问题。
根本问题是,try/ catch
阻止需要finally
,Statement
如果try
处于打开状态,则关闭st
。为此,您需要在try
finally {
if (st != null) {
st.close();
}
}
par, cov = curve_fit(f, x, y, p0=[1.,1.,1.,74.])
答案 2 :(得分:1)
如在另一个响应中所提到的,如果在语句执行期间抛出异常,则会泄漏游标,因为st.close()
将不会被执行。您可以使用Java的try-with-resources语法来确保语句对象已关闭:
try (Statement st = con.createStatement())
{
flag=st.execute(query);
flag=true;
}
catch (Exception e)
{
flag=false;
e.printStackTrace();
throw new SQLException(" UNABLE TO FETCH INSERT");
}
return flag;