Intereting Posts

PDO, mysql, транзакции и блокировка таблицы

Для удовольствия я заменяю расширение mysqli в своем приложении PDO.

Через некоторое время мне нужно использовать транзакции + блокировку таблицы.

В этих ситуациях, согласно руководству mysql, синтаксис должен быть немного другим. Вместо вызова START TRANSACTION вы делаете это так …

SET autocommit=0; LOCK TABLES t1 WRITE, t2 READ, ...; ... do something with tables t1 and t2 here ... COMMIT; UNLOCK TABLES; 

( http://dev.mysql.com/doc/refman/5.0/en/lock-tables-and-transactions.html )

Мой вопрос: как это взаимодействует с PDO :: beginTransaction? Могу ли я использовать PDO :: beginTransaction в этом случае? Или я должен вручную отправить sql «SET autocommit = 0; … и т. Д.».

Спасибо за совет,

Solutions Collecting From Web of "PDO, mysql, транзакции и блокировка таблицы"

В MySQL начало транзакции отличается от выключения автообмена, из-за того, как работает LOCK / UNLOCK TABLES. В MySQL LOCK TABLES совершает любые открытые транзакции, но выключение autocommit фактически не запускает транзакцию. MySQL смешно.

В PDO начало транзакции с использованием beginTransaction фактически не запускает новую транзакцию, она просто отключает автозапуск. В большинстве баз данных это нормально, но может иметь побочные эффекты с упомянутым поведением MySQL.

Вы, вероятно, не должны полагаться на это поведение и то, как он взаимодействует с причудами MySQL. Если вы собираетесь иметь дело с поведением MySQL для блокировки таблиц и DDL, вам следует избегать этого. Если вы хотите отключить автокоммутацию, выключите ее вручную. Если вы хотите открыть транзакцию, откройте транзакцию вручную.

Вы можете свободно смешивать методы API PDO для работы с транзакциями и командами SQL, если в противном случае не работаете с странностями MySQL.

Когда вы вызываете PDO :: beginTransaction () , он отключает автоматическую фиксацию.

Таким образом, вы можете:

 $db->beginTransaction(); $db->exec('LOCK TABLES t1, t2, ...'); # do something with tables $db->commit(); $db->exec('UNLOCK TABLES'); 

После commit () или rollBack () база данных вернется в режим автоматической фиксации.

Я потратил огромное количество времени на эту проблему, и документация по PHP в этой области в лучшем случае расплывчата. Несколько вещей, которые я нашел, запуская PHP 7 с таблицей MySQL InnoDB:

PDO :: beginTransaction не просто отключает автообновление, проверив ответ, полученный Ольховским, с кодом, который не работает, откаты не работают; нет транзакционного поведения. Это означает, что это не может быть так просто.

Начало транзакции может заключаться в блокировке используемых таблиц … Я с нетерпением жду, когда кто-нибудь скажет мне, что я ошибаюсь в этом, но вот причины, по которым это может быть: этот комментарий , который показывает, что таблица была недоступна при начале транзакции , без блокировки. Эта страница документации по PHP , которая проскальзывает в конце:

… пока транзакция активна, вам гарантировано, что никто другой не сможет вносить изменения, пока вы находитесь в середине своей работы

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

Ответ Чарльза Я думаю, что, вероятно, лучше всего, если вы после уверенности с рабочей нагрузкой, которая потребует высокой параллелизма; сделайте это вручную, используя явные запросы к базе данных, затем вы можете перейти к документации базы данных.

Обновление. У меня уже был производственный сервер с использованием функций транзакций PDO, недавно с использованием базы данных Aurora от AWS (полностью совместимой с MySQL, но построенной для автоматического масштабирования и т. Д.). Я доказал эти два момента:

  • Транзакции (чисто способность совершать все изменения базы данных вместе) работают с использованием PDO :: beginTransaction (). Короче говоря, я знаю, что многие сценарии провалились на полпути через выбор / обновление базы данных и сохранность данных.
  • Стоп-блокировки не происходит, у меня была ошибка дублирования индекса, чтобы доказать это.

Итак, чтобы продолжить мой вывод, похоже, что поведение этих функций, похоже, меняется на основе механизма базы данных (и, возможно, других факторов). Насколько я могу судить как по опыту, так и по документации, нет никакого способа узнать программно, что происходит … whoop …