Reputation: 137
I was using batch update prepared statement over millions of record but eventually encountered the following error in runtime after execution of >400k of records.
java.sql.SQLException: ORA-01000: maximum open cursors exceeded
I don't know if this is caused by the following code
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();
}
}
whereby the PreparedStatement is closed and replaced with the new PreparedStatement after the connection is committed. I am not sure if repetitive commit of the same connection may be causing this problem.
Can anyone suggest a solution for the problem or suggest better architecture to handle this batch update of prepared statement.
P/S: the error line actually pointing to delete statement execution, but I don't think this is the root cause, as previously before the batch update prepared statement code is added this problem is not existed.
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();
}
}
Thanks for any suggestion
Upvotes: 3
Views: 4065
Reputation: 6783
One thing that I observed is this:
if(k < objects.length-1)
{
stmt.close();
stmt = conn.prepareStatement(query);
}
Instead of closing
your stmt
object, I would suggest reusing it. This is just an overhead that can be avoided.
I don't think it would serve any purpose to close and re-open the same PreparedStatement
. Also, you can consider calling PreparedStatement.clearParameters()
after addBatch()
Upvotes: 0