Intereting Posts
Скрининг экрана и сеансы PHP Как объединить запросы для нескольких файлов javascript в один HTTP-запрос? Почему index.html имеет приоритет над index.php? php regex, извлечение как regex номера телефона из html документов Каждый радиобутон для каждой формы или 1 формы для всех радиобутов? Как передать файл с JavaScript на PHP? Перенаправить на страницу 404 или отобразить сообщение 404? скрыть видеоконтейнер, когда в базе данных не будет отображаться видео HTML PHP PHP: СЕССИЯ, потерянная на SUBDOMAIN Как использовать функцию array_unique в stdClass Object Array PHP открытие документа MS word без использования com-объекта Вызовите 1 вид в Codeigniter, но поделитесь заголовком / нижним колонтитулом между всеми представлениями? Ошибка PHPExcel в CodeIgniter «Не удалось загрузить запрошенный класс: iofactory» Как получить информацию о файле в определенном пути к каталогу, например, тип файла mime и имя файла с помощью функции php? Не ожидая ответа от запроса AJAX

Автозагрузка в постгресах с использованием 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, чтобы сделать это, когда он считает, что это уместно.

Это не ошибка 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 и исключения для обработки – вы уже опережаете большинство разработчиков.