Вопрос

Я пытаюсь отладить приложение (в 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

Это было полезно?

Решение

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

<Ол>
  • отмените утверждение и начните заново.
  • используйте SAVEPOINT в транзакции, чтобы иметь возможность чтобы вернуться к этому моменту времени и попробовать другой путь. (Это исключение)
  • Включите ведение журнала запросов , чтобы увидеть, какой запрос является ошибочным и почему.

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

    Другие советы

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

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top