ORA-01000:超过了批更新PreparedStatement的最大打开游标数



我在数百万条记录上使用了批更新准备语句,但在执行>400k条记录后,最终在运行时遇到了以下错误。

java.sql.sql异常:ORA-01000:超过的最大打开游标数

我不知道这是否是由以下代码引起的

try{    
conn = ConnectionManager.getConnection();
// turn off autocommit
conn.setAutoCommit(false);
PreparedStatement stmt = conn.prepareStatement(query);
//for each of the records to be updated
for(int k=0;k<objects.length;k++) { 
    stmt.setString(1, objects[k].getValueA());
    stmt.setString(2, objects[k].getValueB());
    stmt.addBatch();
    //running batch execute on every 10000 records
    if(k%10000 == 0 || k == objects.length-1) {
        // submit the batch for execution
        int[] updateCounts = stmt.executeBatch();
        conn.commit();
        if(k < objects.length-1)
        {
            stmt.close();
            stmt = conn.prepareStatement(query);
        }
    }
}
}catch( Exception e ) {
    e.printStackTrace();
}finally {
    if(conn!=null){
        conn.close();
    }
}

从而在提交连接之后关闭PreparedStatement并用新的PreparedSStatement替换。我不确定重复提交同一连接是否会导致此问题。

有人能为这个问题提出解决方案吗?或者建议更好的体系结构来处理准备好的语句的批量更新吗。

p/S:错误行实际上指向删除语句执行,但我不认为这是根本原因,因为之前添加了批更新准备的语句代码之前,这个问题不存在。

try {
    if ( hasData ) {
        conn = ConnectionManager.getConnection();
        CommonStore.deleteRecords( conn, queryStr ); //the error point to this line
        hasData = false;
    }
}catch( Exception e ) {
    e.printStackTrace();
}finally {
    if(conn!=null){
        conn.close();
    }
}

感谢您的任何建议

我观察到的一件事是:

if(k < objects.length-1)
{
    stmt.close();
    stmt = conn.prepareStatement(query);
}

我建议重用stmt对象,而不是closing。这只是可以避免的开销。

我认为关闭并重新打开同一个PreparedStatement没有任何作用。此外,您可以考虑在addBatch() 之后调用PreparedStatement.clearParameters()

最新更新