我在数百万条记录中使用批量更新预处理语句但在执行> 400k记录后最终在运行时遇到以下错误。
java.sql.SQLException: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将关闭并替换为新的PreparedStatement。我不确定重复提交相同的连接是否可能导致此问题。
任何人都可以提出问题的解决方案或建议更好的架构来处理预准备语句的批量更新。
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();
}
}
感谢您的任何建议
答案 0 :(得分:0)
我观察到的一件事是:
if(k < objects.length-1)
{
stmt.close();
stmt = conn.prepareStatement(query);
}
我会建议重复使用,而不是closing
您的stmt
对象。这只是一个可以避免的开销。
我认为关闭并重新打开相同的PreparedStatement
并不会有任何意义。另外,您可以考虑在PreparedStatement.clearParameters()
addBatch()