PDO :: ATTR_AUTOCOMMIT игнорирует нетранзакционную INSERT / UPDATE - PullRequest
8 голосов
/ 01 ноября 2010

Какое-то время царапал мне голову об этом ....

У меня есть объект PDO с pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,0);, так как я хочу использовать FOR UPDATE с некоторыми таблицами InnoDB. Читая документацию MySQL, FOR UPDATE заблокирует только прочитанные строки, если:

  1. Вы находитесь в транзакции
  2. Вы не в транзакции и set autocommit=0 выдано

Итак, я использую ATTR_AUTOCOMMIT, чтобы позволить объекту PDO блокировать строки. В любом случае это приводит к тому, что операторы INSERT и UPDATE не применяются. Эти операторы не имеют ничего общего с FOR UPDATE, они просто проходят через один и тот же объект PDO с подготовленными операторами.

Мой журнал запросов MySQL выглядит так:

xxx    Connect   user@host
xxx    Query     set autocommit=0
xxx    Query     INSERT INTO foo_tbl (bar, baz) VALUES ('hello','world')
xxx    Quit

PHP / PDO не жалуется, но выбор из таблицы показывает, что данные не были записаны.

Запросы, которые я выполняю, выполнялись тысячи раз назад; было изменено только ATTR_AUTOCOMMIT. Удаление этой опции заставляет все работать снова. Транзакции работают нормально с опцией autocommit=0 тоже.

Существуют ли дополнительные вызовы, которые необходимо выполнить для объекта PDO (commit() справедливо жалуется, что он не находится в транзакции), чтобы внести изменения? По сути, я хочу простой объект PDO, но с возможностью блокировки строк вне транзакций для таблиц InnoDB (фон, почему здесь слишком длинный и скучный).

Я уверен, что это что-то глупое, что мне не хватает царапает голову

1 Ответ

7 голосов
/ 02 ноября 2010
    $db = new PDO('mysql:dbname=test');
    $db->setAttribute(PDO::ATTR_AUTOCOMMIT,0);
    var_dump($db->query('SELECT @@autocommit')->fetchAll()); //OK
    $db->query("INSERT INTO foo (bar) VALUES ('a');");
    $db->query("COMMIT;");//do by SQL rather then by interface / PDO-method

Но, по сути, вы находитесь в транзакции (вы просто не начали ее с PDO), откат и т. Д. Также все еще доступны.Это довольно спорно, является ли эта ошибка (не будучи в состоянии назвать commit() непосредственно).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...