Intereting Posts
Как игнорировать ссылку http в строке и возвращать все остальное? Загрузка динамического класса PHP Множественная загрузка изображения с PHP, сохраняющая только один путь к базе данных MySQL Получить выходные дни в php Создать объект Date в PHP для дат до 1970 года в определенном формате Facebook PHP SDK 3 не будет работать на 32-битной системе, иидентификаторы facebook, обработанные как int, и могут быть> 2147483647, лучшее решение? Magento Cron Tab Job Часовой пояс Мой IP-адрес неправильно отображается на домашнем сервере PHP CakePHP: как использовать элемент вида внутри контроллера Предупреждение: mysql_error (): предоставленный аргумент не является допустимым ресурсом MySQL-Link Обновление базы данных из Javascript путем вызова скрипта PHP css / php: как решить эту проблему с float div / нечетный четный цикл в массиве Laravel: Где хранить данные и константы глобальных массивов? как я могу создать функцию возврата успеха? .htaccess; не требуется расширение

Автозагрузка в постгресах с использованием PDO

Я узнал, что предыдущие изменения postgres + PDO отменены, когда выбрано исключение (ДАЖЕ, КОГДА ИСКЛЮЧЕНИЕ ПРОДОЛЖАЕТСЯ И ПОРАЖЕНА!). Пример (в псевдокоде):

$transaction->begin(); try { $manager->insert("INSERT ..."); try { $manager->exec("A QUERY BREAKING SOME DB CONSTRAINT LIKE A UNIQUE INDEX ..."); } catch (\Exception $ex) { // IT IS CAUGHT AND SWALLOWED! } $transaction->commit(); } catch (Exception $ex) { $transaction->rollback(); // THIS CLEARLY DOES NOT RUN! } 

В postgres первая вставка возвращается. В mysql нет.

Может ли кто-нибудь проливать свет на этот вопрос? Можно ли изменить это смехотворное поведение? Я хотел бы сам выполнить свои откаты и не получить pg, чтобы сделать это, когда он считает, что это уместно.

Related of "Автозагрузка в постгресах с использованием PDO"

Это не ошибка PDO, она присуща управлению транзакциями PostgreSQL. Видеть:

  • Как я могу сообщить PostgreSQL о том, чтобы не прервать всю транзакцию, когда одно ограничение завершилось неудачей?
  • Могу ли я попросить Postgresql игнорировать ошибки в транзакции
  • Откат после ошибки в транзакции

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

ERROR: current transaction is aborted, commands ignored until end of transaction block

(Я удивлен, чтобы не найти это в официальной документации, думаю, мне нужно написать патч, чтобы улучшить это.)

Так. Когда вы пытаетесь / улавливаете и проглатываете исключение в PDO, вы захватываете исключение PHP-стороны, но вы не меняете того факта, что транзакция PostgreSQL находится в состоянии прервана.

Если вы хотите иметь возможность перехватывать исключения и продолжать использовать транзакцию, вы должны создать SAVEPOINT перед каждым оператором, который может выйти из строя. Если он терпит неудачу, вы должны ROLLBACK TO SAVEPOINT ...; , Если это удастся, вы можете RELEASE SAVEPOINT ...; , Это накладывает дополнительные накладные расходы на базу данных для управления транзакциями, добавляет округлые поездки и быстрее сжигает идентификаторы транзакций (это означает, что PostgreSQL должен выполнять дополнительную работу по очистке фона).

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

Если это нецелесообразно, сделайте ваш отказ от приложения терпимым, чтобы он мог повторить неудачную транзакцию. Иногда это необходимо в любом случае – например, вы не можете вообще использовать точки сохранения для восстановления от сбоев транзакций или сбоев сериализации. Также может быть полезно, чтобы как можно более короткие транзакции, связанные с отказом, выполняли минимальную требуемую работу, поэтому вам нужно меньше отслеживать и повторять.

Итак: где это возможно, вместо проглатывания исключения, запускайте код базы данных, подверженный ошибкам, в цикле повтора. Убедитесь, что ваш код хранит запись информации, которая ему нужна, чтобы повторить всю транзакцию по ошибке, а не только последнее утверждение.

Помните, что любая транзакция может потерпеть неудачу: администратор баз данных может перезапустить базу данных для применения патча, система может закончиться из-за работы из-за беглого задания cron и т. Д. Таким образом, отказоустойчивые приложения – хороший дизайн.

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