Почему совершается следующая транзакция PDO? - PullRequest
7 голосов
/ 26 июля 2010

Я думаю, что сам вопрос довольно понятен. Код приведен ниже -

<?php
    $PDO = NULL;
    $pdo_dsn = 'mysql:host=localhost;dbname=pdo_test';
    $pdo_persistence = array( PDO::ATTR_PERSISTENT => true );
    $db_user = 'root';
    $db_pass = '';
    $db_query = "INSERT INTO person(name, address)
                    VALUES ('Mamsi Mamsi', 'Katabon')";

    try
    {
            $PDO = new PDO($pdo_dsn, $db_user, $db_pass, 
                              $pdo_persistence);
    }
    catch(PDOException $e)
    {
            echo "Error occured: ". $e->getMessage();
            die();
    }

    $PDO->setAttribute(PDO::ATTR_ERRMODE, 
                           PDO::ERRMODE_EXCEPTION);
    $PDO->setAttribute(PDO::ATTR_AUTOCOMMIT, false);

    try
    {
            $PDO->beginTransaction();
            $PDO->exec($db_query);

            throw new PDOException('Generated Exception');

            $PDO->commit();
    }
    catch(PDOException $e)
    {
            echo "An error occured while doing a database transaction. The 
            error message is : ".$e->getMessage();

            $PDO->rollBack();
            die();
    }
?>

Даже если я откатываю транзакцию внутри блока catch, данные все равно вставляются в базу данных. Почему?

EDIT

Я добавляю следующие несколько строк из документации для дальнейшего уточнения -

К сожалению, не каждая база данных поддерживает транзакции, поэтому PDO необходимо работать в так называемом режиме автоматической фиксации при первом открытии подключение. Режим автоматической фиксации означает, что каждый выполняемый вами запрос имеет свою собственную неявную транзакцию, если база данных поддерживает ее или нет транзакция, если база данных не поддерживает транзакции. Если тебе надо транзакции, вы должны использовать метод PDO :: beginTransaction () для инициировать один. Если базовый драйвер не поддерживает транзакции, будет выдано исключение PDOException (независимо от вашей обработки ошибок настройки: это всегда серьезная ошибка). Как только вы в транзакция, вы можете использовать PDO :: commit () или PDO :: rollBack () для завершения это, в зависимости от успеха кода, который вы запускаете во время сделка.

Кроме того, следующие строки из этой страницы -

bool PDO::beginTransaction  ( void  )

Отключение режима автоматической фиксации. Пока режим автоматической фиксации выключен, изменения, внесенные в базу данных через экземпляр объекта PDO, не являются совершено, пока вы не завершите транзакцию, вызвав PDO :: commit (). Вызов PDO :: rollBack () откатит все изменения в базе данных и верните соединение в режим автоматической фиксации.

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

1 Ответ

16 голосов
/ 26 июля 2010

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

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