我正在使用 JDBC,并且 autocommit=true。在其中一项操作中,我使用准备好的语句进行批量插入。
public void executeBatchInsert(String query, List<Object[]> entityList) {
try {
pstmt = conn.prepareStatement(query);
for(int i=0; i<entityList.size(); i++) {
int j=1;
for(Object o: entityList.get(i)) {
pstmt.setObject(j++, formatColumnValue(o));
}
pstmt.addBatch();
if((i+1)%1000 == 0) {
pstmt.executeBatch();
}
}
pstmt.executeBatch();
} catch (SQLException e) {
}
}
如果我在执行时遇到异常,当我关闭此连接时,是否会释放所有锁并发生回滚?
-- B.泰贾。
最佳答案
你的问题的直接答案是:不。如果发生异常,您必须手动调用rollback
方法。在此之前,您必须将 setAutoCommit
设置为 false
。默认情况下,自动提交设置为 true
。将自动提交设置为 true
后,您无法执行回滚
,将会发生异常
,告诉您这一点。
稍后不要忘记将 autoCommit
设置回 true
,否则您可能会使用其他方法得到不可预期的结果。
以下是有关如何实现此功能的示例。这只是一个草图,您可能应该更多地关注如何处理连接
、准备好的语句
、异常
等。
public void insertAndRollback(Connection connection) {
try {
final ArrayList parameters = new ArrayList();
// Add your parameters to the arraylist
parameters.add("John");
parameters.add("Lee");
parameters.add("Mary");
parameters.add("Peter");
parameters.add("Lewis");
parameters.add("Patrick");
final String parameterizedQuery = "insert into person (name) values (?)";
final int batchSize = 5; // Set your batch size here
int count = 0;
int aux = 0;
// Get the total number of '?' in the query
int totalQueryParameters = Utils.countCharOccurrences(parameterizedQuery, '?');
final int auxTotalQueryParameters = totalQueryParameters;
final PreparedStatement preparedStatement = connection.prepareStatement(parameterizedQuery);
// Auto Commit must be set to false
connection.setAutoCommit(false);
for(int i = 0; i < parameters.size(); i++)
{
Object obj = parameters.get(i);
aux++;
preparedStatement.setObject(aux, obj);
if(totalQueryParameters == i + 1) { // Because the ArrayList starts from zero.
// First query "parsed" - > Add to batch
preparedStatement.addBatch();
// One query has been added to the batch. Re-adapt the cycle.
totalQueryParameters = totalQueryParameters + auxTotalQueryParameters;
aux = 0;
}
if(++count % batchSize == 0) {
preparedStatement.executeBatch();
}
}
preparedStatement.executeBatch(); // insert remaining queries
preparedStatement.close();
connection.setAutoCommit(true); // Make it back to default.
} catch (SQLException ex) {
// Do the rollback
doRollback(connection);
try {
// Make it back to default.
connection.setAutoCommit(true);
} catch (SQLException ex1) {
ex1.printStackTrace();
}
// Dont forget to close the preparedStatement and the connection
// if you don't need the connection open any more.
ex.printStackTrace();
}
}
private void doRollback(Connection c) {
try {
c.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
关于java - 使用带有 autocommit=true 的 jdbc 时回滚批处理执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14625371/