Spring JdbcTemplate batchUpdate для обработки исключений - PullRequest
3 голосов
/ 21 марта 2012

В настоящее время наш код использует метод batchUpdate JdbcTemplate для пакетной вставки.

У меня вопрос в случае какого-либо исключения в одном из обновлений, как его обработать (допустим, просто добавив журнал) и продолжить следующее обновление SQL-операторов?

Также, как метод batchUpdate () для JdbcTemplate обрабатывает исключения?

Фрагмент здесь.

    /**
     * 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 ]

6 голосов
/ 22 марта 2012

как метод batchUpdate () для JdbcTemplate обрабатывает исключения?

Поведение пакетного обновления не определено в JDBC :

Если одна из команд в пакетном обновлении не выполняется должным образом, этот метод генерирует исключение BatchUpdateException, и драйвер JDBC может продолжать или не обрабатывать оставшиеся команды в пакете.

Вам следует проверить это поведение в вашей СУБД.

В любом случае, BatchUpdateException будет перехвачен пружиной и перезапущен как RuntimeException после некоторой очистки (см. Подробности реализации здесь ).

Вся эта логика будет переплетаться с транзакциями - например, если вставка находится в границах транзакции и вы перебрасываете RuntimeException через границы транзакции - транзакция (и все успешные вставки с ней) будет откатываться.

Поэтому желаемая пакетная логика «только строки ошибок журнала» не может быть эффективно реализована без дополнительных знаний о вашей СУБД и ее поведении драйвера JDBC при ошибках во время пакетных вставок.

0 голосов
/ 16 апреля 2014

Я столкнулся с той же проблемой, что 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
            }

        }
...