目前我们的代码使用JdbcTemplate的batchUpdate方法来进行批量插入。
我的问题是,如果某个更新中出现任何异常,如何处理它(假设只是通过添加日志)并继续执行下一个更新sql语句?
JdbcTemplate的batchUpdate()方法如何处理异常?
这里是狙击手。
/**
* 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));
}
}
JdbcTemplate的batchUpdate()方法如何处理异常?
JDBC中未定义批更新行为:
如果批处理更新中的某个命令未能正确执行,则此方法会抛出BatchUpdateException,JDBC驱动程序可能会也可能不会继续处理批处理中的其余命令。
您应该使用DBMS检查这种行为。
无论如何,BatchUpdateException
将被spring捕获,并在经过一些清理后作为RuntimeException重新抛出(请参阅此处的实现详细信息)。
所有这些逻辑都将与事务交织在一起——例如,如果insert在事务边界内,并且您通过事务边界重新抛出RuntimeException
——事务(以及所有成功的插入)将被回滚。
如果不了解DBMS及其JDBC驱动程序在批插入期间对错误的行为,那么所需的"仅记录错误行"批处理逻辑就无法有效实现。
我遇到了同样的问题,即spring-jdbc在出现任何错误记录时停止插入,并且不继续插入。以下是我的工作:-
// 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
}
}