Spring JdbcTemplate batchUpdate处理异常

时间:2012-03-21 17:11:05

标签: spring jdbc jdbctemplate spring-jdbc batch-updates

目前我们的代码使用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));
        }
    }

2 个答案:

答案 0 :(得分:6)

  

JdbcTemplate的batchUpdate()方法如何处理异常?

批量更新行为为undefined in JDBC

  

如果批量更新中的某个命令无法正确执行,则此方法将抛出BatchUpdateException,并且JDBC驱动程序可能会也可能不会继续处理批处理中的其余命令。

您应该使用DBMS检查此行为。

无论如何,BatchUpdateException将被spring捕获并在一些清理后重新抛出RuntimeException(请参阅实现细节here)。

所有这些逻辑将与交易相互交织 - 例如如果insert在事务范围内,并且您通过事务边界重新抛出RuntimeException - 事务(以及所有成功插入)将被回滚。

如果没有关于DBMS的额外知识,并且在批量插入过程中出现错误的JDBC驱动程序行为,那么期望的“仅限日志错误行”批处理逻辑无法有效实现。

答案 1 :(得分:0)

我遇到了同样的问题,即如果有任何错误记录,并且没有继续插入,则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
            }

        }