Транзакция, хранимая процедура и PDO

Одно действие в PHP должно пройти следующие этапы:

  1. Выполнить нет. операторов mysql из PHP PDO, основанных на большом количестве бизнес-логики.
  2. Выполнить хранимую процедуру.
  3. Выполните еще несколько операторов MySQL из PDO.

Весь процесс должен быть одной транзакцией. Если в хранимой процедуре MySQL происходит какая-либо ошибка, необходимо откатить всю транзакцию. (Хранимая процедура имеет запросы для создания временных таблиц, выполнения сканирования на основе курсора и выполнения вставок.) Даже если ошибка возникает в PDO после хранимой процедуры, транзакция должна быть полностью откатана, включая любые изменения, которые произошли в хранимая процедура.

Запросы на основе PDO были запрограммированы довольно давно. И хранимая процедура вводится заново в соответствии с новыми требованиями клиента.

В PHP транзакция запускается в начале шага 1. И есть фиксация в конце шага 3. И есть блок catch в конце, который вызывает откат.

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

Если нет, гарантируется ли атомарность всего действия?


person mohitp    schedule 05.10.2012    source источник
comment
Сохраненная процедура будет частью транзакции, которую вы начнете через PDO. Естественно, вам придется использовать механизм хранения, поддерживающий транзакции.   -  person N.B.    schedule 05.10.2012
comment
Интересный вопрос. Я не думаю, что PDO изначально поддерживает вложенные транзакции. Вероятно, вы могли бы использовать точки сохранения   -  person Madara's Ghost    schedule 05.10.2012
comment
@ N.B .: Я просто попробовал, внося ошибку в хранимую процедуру. И действие не откатилось. Фактически, все изменения до момента ошибки были зафиксированы (включая те, которые произошли до вызова хранимой процедуры). Механизм хранения - InnoDB.   -  person mohitp    schedule 05.10.2012
comment
Я держу пари, что дескриптор PDO db и подразумеваемый дескриптор в SP отличаются. Транзакция не будет разделена между ними. Однако я не могу найти какого-либо конкретного утверждения, которое бы это показывало.   -  person ethrbunny    schedule 05.10.2012
comment
@ N.B .: Только что обнаружил, что фиксация была вызвана ошибкой кодирования в моей хранимой процедуре. Перед созданием временной таблицы я выдавал оператор Drop Table без ключевого слова Temporary, которое вызывало автоматическую фиксацию. Как вы упомянули, хранимая процедура кажется частью транзакции. Для полноты картины и в помощь такому запутавшемуся кодеру, как я, это примечание из документации MySQL Во всех сохраненных программах синтаксический анализатор рассматривает BEGIN как начало блока BEGIN ... END. Вместо этого начните транзакцию в этом контексте с START TRANSACTION   -  person mohitp    schedule 06.10.2012


Ответы (1)


Это ссылка на цитату Мохипа: http://dev.mysql.com/doc/refman/5.6/en/begin-end.html Транзакция не запускается в хранимой процедуре автоматически, необходимо вызвать ее командой «НАЧАТЬ ТРАНЗАКЦИЮ», я собирался задать этот вопрос. Спасибо за цитату.

person N Zhang    schedule 01.03.2013