Для удовольствия я заменяю расширение 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; … и т. Д.».
Спасибо за совет,
В 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, но построенной для автоматического масштабирования и т. Д.). Я доказал эти два момента:
Итак, чтобы продолжить мой вывод, похоже, что поведение этих функций, похоже, меняется на основе механизма базы данных (и, возможно, других факторов). Насколько я могу судить как по опыту, так и по документации, нет никакого способа узнать программно, что происходит … whoop …