问题
Currently our code uses batchUpdate method of JdbcTemplate to do batch Insertion.
My question is in case of any exception in one of the update how to handle it (suppose just by adding the log) and continue with the next update sql statements?
Also how batchUpdate() method fo JdbcTemplate handles the exceptions?
Snippet here.
/**
* Saves the list of <code>Item</code> objects to the database in a batch mode
*
* @param objects
* list of objects to save in a batch mode
*/
public void save(final List<Item> listOfItems) {
for (List<Debit> list : listOfItems) {
getJdbcTemplate().batchUpdate(insertItem, new ItemBatchPreparedStatementSetter(list));
}
}
回答1:
how batchUpdate() method fo JdbcTemplate handles the exceptions?
Batch update behavior is undefined in JDBC:
If one of the commands in a batch update fails to execute properly, this method throws a BatchUpdateException, and a JDBC driver may or may not continue to process the remaining commands in the batch.
You should check this behavior with your DBMS.
Anyway, BatchUpdateException
will be caught by spring and rethrown as RuntimeException after some clean up (see implementation details here).
All this logic will be interwined with transactions - e.g. if insert is within transaction bounds and you rethrow RuntimeException
through transaction bounds - transaction (and all successful inserts with it) will be rolled back.
So desired "log error rows only" batch logic cannot be implemented effectively without additional knowledge about your DBMS and it's JDBC driver behaviour on errors during batch inserts.
回答2:
I ran into the same problem that spring jdbc stops insertion in case of any error record and does not continue insertion. Below is my work around :-
// divide the inputlist into batches and for each batch :-
for (int j = 0; j < resEntlSize; j += getEntlBatchSize()) {
final List<ResEntlDTO> batchEntlDTOList = resEntlDTOList
.subList(
j,
j + getEntlBatchSize() > resEntlSize ? resEntlSize
: j + getEntlBatchSize());
TransactionDefinition def = new DefaultTransactionDefinition();
TransactionStatus status = transactionManager
.getTransaction(def);
try {
//perform batchupdate for the batch
transactionManager.commit(status);
} catch (Exception e) {
transactionManager.rollback(status);
//perform single update for the error batch
}
}
来源:https://stackoverflow.com/questions/9809503/spring-jdbctemplate-batchupdate-handling-exceptions