为什么以下PDO事务会提交?

MD *_*med 7 php pdo

我认为这个问题本身就是不言自明的.代码如下 -

<?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();
    }
?>
Run Code Online (Sandbox Code Playgroud)

即使我在catch块中回滚事务,数据仍然被插入到数据库中.为什么?

编辑

我将从文档中添加以下几行以进一步说明 -

不幸的是,并非每个数据库都支持事务,因此当您第一次打开连接时,PDO需要以所谓的"自动提交"模式运行.自动提交模式意味着您运行的每个查询都有自己的隐式事务(如果数据库支持它),或者如果数据库不支持事务则没有事务.如果需要事务,则必须使用PDO :: beginTransaction()方法来启动事务.如果底层驱动程序不支持事务,则抛出PDOException(无论您的错误处理设置如何:这始终是一个严重的错误条件).进入事务后,您可以使用PDO :: commit()或PDO :: rollBack()来完成它,具体取决于您在事务期间运行的代码是否成功.

此外,页面的以下行-

bool PDO::beginTransaction  ( void  )
Run Code Online (Sandbox Code Playgroud)

关闭自动提交模式.在关闭自动提交模式时,在通过调用PDO :: commit()结束事务之前,不会提交通过PDO对象实例对数据库所做的更改.调用PDO :: rollBack()将回滚对数据库的所有更改并将连接返回到自动提交模式.

当在事务中发出数据库定义语言(DDL)语句(如DROP TABLE或CREATE TABLE)时,某些数据库(包括MySQL)会自动发出隐式COMMIT.隐式COMMIT将阻止您回滚事务边界内的任何其他更改.

Jim*_* W. 16

您应该检查您是否使用INNODB作为数据库类型.MyISAM不支持交易.