PDO:事务不回滚?

Posted

技术标签:

【中文标题】PDO:事务不回滚?【英文标题】:PDO: Transactions don't roll back? 【发布时间】:2011-01-26 10:45:16 【问题描述】:

我正在通过this tutorial 了解 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();

它运行得很好,就像我想的那样,除非我在某个地方输入了错误。就像我在第四个插入语句中创建了一个错误一样,我会在我的数据库中找到三只动物。但我认为事情应该被回滚,这意味着我会在运行这个脚本之前找到数据库。

我是不是误会了什么?我错过了什么?事务和回滚函数是否做了我认为它们应该做的其他事情? drop 和 create 语句是否以某种方式“破坏”了事务?这是怎么回事?


更新:如果我移动 $db->beginTransaction(); 行以便事务仅在表创建后开始,我会得到我所期望的行为。因此,如果第三个插入语句随后失败,则在事务回滚后我将有一个空表(因为它刚刚重新创建)。仍然想知道为什么当 drop 和 create 语句在事务中时它不起作用...

【问题讨论】:

【参考方案1】:

查看 PHP 参考手册:PDO::beginTransaction

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

这解释了为什么会发生这种情况,这是 MySQL 的限制,而不是 PDO/PHP 的限制。

【讨论】:

啊哈。这就说得通了!谢谢你:)【参考方案2】:

确保所有表都支持事务。 例如 MyISAM 不支持。

【讨论】:

这更像是一个评论而不是一个答案。

以上是关于PDO:事务不回滚?的主要内容,如果未能解决你的问题,请参考以下文章

spring配置了事务,抛出异常不回滚

@Transaction不回滚事务问题

MySQL事务不回滚会有啥影响?

面试突击86:SpringBoot 事务不回滚?怎么解决?

事务在休眠中不回滚

Spring boot,测试后事务不回滚