何百万ものレコードに対してバッチ更新の準備済みステートメントを使用していましたが、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();
}
}
提案をありがとう