Я делаю пакетные вставки с помощью драйвера postgres 9.3-1100-jdbc41 JDBC4.
Согласно спецификации JDBC, ее приложение может отключить автообновление и совершить или отменить транзакцию.
В моем случае я не использую никаких транзакций (т.е. Автообложение является истинным), но все же вставки откатятся, если одна из вложений в пакете терпит неудачу.
Согласно спецификации JDBC "Если одна из команд в пакетном обновлении не выполняется должным образом, этот метод генерирует исключение BatchUpdateException, а драйвер JDBC может или не может обрабатывать оставшиеся команды в пакете". Здесь он не говорит, что ранее выполненные команды будут отброшены назад.
Я понимаю, что неправильно? Если нет, то почему драйвер ведет себя таким образом, и если да, то каково правильное поведение в соответствии со спецификацией.
Насколько я могу судить, спецификация по существу оставляет это до водителя; он не указывает, совершена ли уже обработанная работа, если пакет завершился с ошибкой.
PgJDBC выполняет партию в транзакции, поэтому, если какая-либо часть пакета терпит неудачу, она будет прервана.
Если вы считаете, что это поведение неверно, первое, что вам нужно сделать, это написать тестовый пример, демонстрирующий, что другие драйверы ведут себя по-разному к PgJDBC и отправляют его в трекер PgJDBC. У нас нет времени для исследования поведения других драйверов, поэтому вам нужно написать тестовый пример и запустить его в некоторых других популярных базах данных (MS SQL Server, Oracle, DB2, MySQL и т.д.) Или организовать его запуск другими. Если вы обнаружите, что поведение PgJDBC отличается от того, как другие драйверы обрабатывают партии, тогда стоит подумать о добавлении опции для изменения поведения (и в конечном итоге сделать это по умолчанию).
PreparedStatement
(о чем я и предполагаю, что этот вопрос) отправляются в виде одного сообщения Parse
по сети, за которым следуют несколько сообщений Bind/Describe/Execute
, по одному на каждую запись пакета. Если транзакция еще не открыта, она открывается с начальным значением BEGIN
и завершением COMMIT
. Сделать это в autocommit тривиально, исключив операторы оберточной транзакции.
insert into .. values (..),(..),(..),(..)
)