Транзакции, когда должны быть отменены и откат - PullRequest
1 голос
/ 12 октября 2008

Я пытаюсь отладить приложение (под PostgreSQL) и наткнулся на следующую ошибку: "текущая транзакция прервана, команды проигнорированы".

Насколько я понимаю, "транзакция" - это просто понятие, относящееся к базовому соединению с базой данных.

Если в соединении есть автоматическая фиксация "false", вы можете выполнять запросы через один и тот же оператор, если он не дает сбоя. В этом случае вы должны выполнить откат.

Если автоматическая фиксация имеет значение "true", это не имеет значения, если все ваши запросы считаются атомарными.

Используя auto commit false, я получаю вышеупомянутую ошибку от PostgreSQL, даже если просто

select * from foo

терпит неудачу, что заставляет меня спросить, при каких условиях SQLException является "транзакцией", считающейся недействительной, и должна откатываться назад или не использоваться для другого запроса?

с использованием MacOS 10.5, Java 1.5.0_16, PostgreSQL 8.3 с драйвером JDBC 8.1-407.jdbc3

Ответы [ 2 ]

3 голосов
/ 12 октября 2008

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

  1. отменить утверждение и начать заново.
  2. используйте SAVEPOINT s в транзакции, чтобы иметь возможность вернуться к этому моменту времени и попробовать другой путь. (Это исключение)

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

В любом случае точный ответ на ваш вопрос заключается в том, что любое исключение SQLException должно означать, что откат произошел при отправке команды завершения транзакции, то есть при выполнении команды COMMIT или ROLLBACK (или END). Вот как это работает: если вы используете точки сохранения, вы все равно будете придерживаться тех же правил, вы просто сможете вернуться туда, где вы сохранили, и попробовать что-то еще.

1 голос
/ 12 октября 2008

Кажется, что это характерное поведение PostgreSQL, которое не используется большинством других СУБД. В целом (за пределами PostgreSQL) вы можете потерпеть неудачу в одной операции из-за ошибки, а затем в той же транзакции можете попробовать выполнить альтернативные действия, которые завершатся успешно, компенсируя ошибку. Один пример: рассмотрим операцию объединения (вставки / обновления). Если вы попытаетесь ВСТАВИТЬ новую запись, но обнаружите, что она уже существует, вы можете переключиться на операцию ОБНОВЛЕНИЕ, которая вместо этого изменяет существующую запись. Это прекрасно работает во всех основных СУБД. Я не уверен, что он не работает в PostgreSQL, но описания, которые я видел в других местах, а также в этом вопросе, предполагают, что когда попытка INSERT означает, что любая дальнейшая активность в транзакции обречена на провал. Что в лучшем случае драконовское, а в худшем «непригодное».

...