BatchUpdateException: пакет не будет прерван - PullRequest
9 голосов
/ 18 января 2011

У меня есть приложение, которое обрабатывает очень большой файл и отправляет данные в базу данных Oracle (используя Java 6, Oracle 9).

В цикле я использую PreparedStatement ps и создаю все операторы SQL, сгенерированные с помощью ps.addBatch().

. У меня есть ситуация, когда BatchUpdateException bue выбрасывается где-то во время ps.executeBatch(),В этот момент выполнение пакета прекращается.

Я бы хотел, чтобы выполнение пакета продолжилось, чтобы затем я мог проверить наличие неудачных обновлений в методе processUpdateCounts(bue.getUpdateCounts()).

.Javadoc о классе BatchUpdateException говорит:

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

Есть ли способ принудительного продолжения или мне нужно изменить мою программу, чтобы она выполняла оператор по отдельности?

Ответы [ 4 ]

5 голосов
/ 18 января 2011

Только что нашел эту ссылку: Проблема пакетного обновления JDBC

Видимо, там написано

НЕТ ПУТИ С ORACLE BATCH JDBC для продолжения после первого сбоя ,

поэтому я прибегаю к отправке вкладок одна за другой. Спасибо

(извините, что не выгляжу лучше, чтобы найти ссылку выше).

3 голосов
/ 18 января 2011

есть обходной путь, который позволит вам использовать пакетную функцию.Вместо выполнения простого оператора INSERT вы можете выполнить блок PL / SQL, который будет соответствующим образом обрабатывать ошибку:

BEGIN
   INSERT INTO your_table VALUES (?,?,...?);
EXCEPTION
   WHEN OTHERS THEN
      /* deal with the error. For example, log the error id and error msg 
         so that you can list them after the batch */
      INSERT INTO error_table VALUES (?, sqlerrm);
END

Производительность должна быть на уровне пакетной вставки (должна быть быстрее, чем отдельное выполнениеиз заявлений).Вы также можете вызвать хранимую процедуру вместо блока PL / SQL.

1 голос
/ 18 января 2011

Сам Oracle может, см. Здесь: http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14250/oci04sql.htm#sthref616

Однако, похоже, что эта функциональность не предоставляется JDBC, даже в определенных классах Oracle.

Из-задовольно бесполезная обработка ошибок JDBC («драйвер может продолжаться или не продолжаться»), я всегда устанавливаю точку сохранения перед пакетом и выполняю откат до этой точки при ошибке.Насколько мне известно, это единственный совместимый с JDBC способ установления известного состояния после ошибки пакета Oracle.

0 голосов
/ 18 января 2011

Так как спецификация, кажется, не предписывает это (как ясно показано в Javadoc), любое «принудительное» продолжение должно быть сделано для каждого драйвера.Простой совместимый со стандартом обходной путь должен был бы проверить возвращаемый массив getUpdateCounts() и «перезапустить» пакет для тех операторов, которые потерпели неудачу.Вы можете сделать этот подход немного более сложным, введя логику для количества повторных попыток.

Конечно, это кажется немного грязным (отслеживание добавленной "партии" и затем проверка вывода), ноработать со всеми базами данных и реализациями драйверов.Просто мысль ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...