【问题标题】:Spring JdbcTemplate batchUpdate handling exceptionsSpring JdbcTemplate batchUpdate 处理异常
【发布时间】:2012-04-06 06:14:33
【问题描述】:

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

【问题讨论】:

  • 在批量更新中处理错误并不容易,并且没有一种解决方案。这取决于想要如何处理它。
  • @skaffman 你知道处理 Spring 批量更新错误的方法吗?当使用异常翻译时,似乎第一个遇到的被翻译并抛出,因此返回的更新计数丢失。这很奇怪。

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


【解决方案1】:

我遇到了同样的问题,即 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
            }

        }

【讨论】:

    【解决方案2】:

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

    批量更新行为为undefined in JDBC:

    如果批量更新中的某个命令未能正确执行,此方法会抛出 BatchUpdateException,JDBC 驱动程序可能会或可能不会继续处理批处理中剩余的命令。

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

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

    所有这些逻辑都将与交易交织在一起——例如如果插入在事务范围内并且您通过事务范围重新抛出RuntimeException - 事务(以及所有成功的插入)将被回滚。

    因此,如果没有额外的关于您的 DBMS 的知识以及批处理插入期间错误的 JDBC 驱动程序行为,就无法有效地实现所需的“仅记录错误行”批处理逻辑。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-30
      • 1970-01-01
      • 2017-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-17
      • 2023-03-28
      相关资源
      最近更新 更多