Пакетное обновление в драйвере Postgresql JDBC откатывается в автокоммит

1

Я делаю пакетные вставки с помощью драйвера postgres 9.3-1100-jdbc41 JDBC4.

Согласно спецификации JDBC, ее приложение может отключить автообновление и совершить или отменить транзакцию.

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

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

Я понимаю, что неправильно? Если нет, то почему драйвер ведет себя таким образом, и если да, то каково правильное поведение в соответствии со спецификацией.

  • 3
    Если вы используете автоматическую фиксацию, все пакетные вставки все еще выполняются в одной транзакции, если я не ошибаюсь. Думайте об этом как об ином способе записи одной вставки, которая вставляет много строк ( insert into .. values (..),(..),(..),(..) )
  • 0
    Спасибо за ваш ответ. Но как насчет спецификации. Я думаю, что это просто, чтобы избежать обходов по сети для каждой вставки и применять транзакции должно быть в зависимости от приложения. На БД каждая вставка должна быть выполнена как единое целое. Как пользователь, я могу добавить несвязанные вставки в один пакет, чтобы избежать обратной передачи, которую не следует откатывать в случае сбоя какой-либо команды.
Показать ещё 3 комментария
Теги:
jdbc

1 ответ

1

Насколько я могу судить, спецификация по существу оставляет это до водителя; он не указывает, совершена ли уже обработанная работа, если пакет завершился с ошибкой.

PgJDBC выполняет партию в транзакции, поэтому, если какая-либо часть пакета терпит неудачу, она будет прервана.

Если вы считаете, что это поведение неверно, первое, что вам нужно сделать, это написать тестовый пример, демонстрирующий, что другие драйверы ведут себя по-разному к PgJDBC и отправляют его в трекер PgJDBC. У нас нет времени для исследования поведения других драйверов, поэтому вам нужно написать тестовый пример и запустить его в некоторых других популярных базах данных (MS SQL Server, Oracle, DB2, MySQL и т.д.) Или организовать его запуск другими. Если вы обнаружите, что поведение PgJDBC отличается от того, как другие драйверы обрабатывают партии, тогда стоит подумать о добавлении опции для изменения поведения (и в конечном итоге сделать это по умолчанию).

  • 1
    Я не думаю, что вы можете изменить поведение драйвера - в конце концов, сам Postgres не позволяет совершить транзакцию, если один оператор потерпел неудачу. Это отличается, например, в Oracle, где вы можете зафиксировать транзакцию, даже если промежуточный оператор DML не удался.
  • 0
    @a_horse_with_no_name При желании можно изменить поведение водителя в этом случае. PreparedStatement (о чем я и предполагаю, что этот вопрос) отправляются в виде одного сообщения Parse по сети, за которым следуют несколько сообщений Bind/Describe/Execute , по одному на каждую запись пакета. Если транзакция еще не открыта, она открывается с начальным значением BEGIN и завершением COMMIT . Сделать это в autocommit тривиально, исключив операторы оберточной транзакции.
Показать ещё 7 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню