PDO: транзакции не откатываются? - PullRequest
8 голосов
/ 11 марта 2010

Я прошёл этот урок о PDO и подошел к вопросу о транзакциях. Пропустив части подключения, у меня есть этот php-код:

try
{
    $db->beginTransaction();

    $db->exec('DROP TABLE IF EXISTS animals');

    $db->exec('CREATE TABLE animals ('
        .'animal_id MEDIUMINT(8) NOT NULL AUTO_INCREMENT PRIMARY KEY,'
        .'animal_type VARCHAR(25) NOT NULL,'
        .'animal_name VARCHAR(25) NOT NULL)'
        .'ENGINE=INNODB');

    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("emu", "bruce")');
    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("funnel web", "bruce")');
    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("lizard", "bruce")');
    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("dingo", "bruce")');
    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("kangaroo", "bruce")');
    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("wallaby", "bruce")');
    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("wombat", "bruce")');
    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("koala", "bruce")');
    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("kiwi", "bruce")');

    $db->commit();

    echo 'Table re-created and data entered successfully.';
}
catch(PDOException $e)
{
    $db->rollback();

    echo $e->getMessage();
}

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

Я что-то не так понял? Что мне не хватает? Функции транзакции и отката делают что-то еще, чем я думаю, что они должны делать? Является ли отбрасывание и создание операторов как-то "нарушает" транзакцию? Что здесь происходит?


Обновление: Если переместить строку $db->beginTransaction();, чтобы транзакция началась только после создания таблицы, я получаю ожидаемое поведение. Таким образом, если третий оператор вставки затем потерпел неудачу, у меня была бы пустая таблица (так как она была просто воссоздана) после отката транзакции. Все еще задаюсь вопросом, почему это не работает, когда операторы drop и create находятся в транзакции, хотя ...

Ответы [ 2 ]

19 голосов
/ 11 марта 2010

Проверьте справочное руководство по PHP: PDO :: beginTransaction

Некоторые базы данных, включая MySQL, автоматически выдают неявный COMMIT, когда в транзакции выдается оператор языка определения базы данных (DDL), такой как DROP TABLE или CREATE TABLE. Неявный COMMIT не позволит вам откатить любые другие изменения в пределах границы транзакции.

Это объясняет, почему это происходит, и это ограничение MySQL, а не PDO / PHP.

2 голосов
/ 18 августа 2012

убедитесь, что все таблицы поддерживают транзакции. например, MyISAM не поддерживает.

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