【问题标题】:PHP PDO transaction automatic rollBackPHP PDO 事务自动回滚
【发布时间】:2013-05-13 17:41:52
【问题描述】:

我只是在我最近从使用 PHP ADODB 库转换为 PDO 的一个应用程序上改进了一些代码。在 adodb 中,一旦你启动了一个事务,如果 begin 和 commit 命令之间的查询出现任何异常,它会自动回滚。

PDO 是否也这样做。如果一个有查询的方法在 PDO 中的 begin 和 commit 之间失败,那么 trsaction 会自动回滚还是需要隐式调用?

【问题讨论】:

    标签: php pdo transactions


    【解决方案1】:

    您必须自己调用回滚(并提交),PDO 不会为您执行此操作。像这样的:

    $pdo = new \PDO(/* ... */);
    
    $pdo->beginTransaction();
    
    try {
        // do stuff..
    } catch(\Throwable $e) { // use \Exception in PHP < 7.0
        $pdo->rollBack();
        throw $e;
    }
    
    $pdo->commit();
    

    但是,PDO 将rollback any open transactions when a script ends

    当脚本结束或连接即将关闭时,如果有未完成的事务,PDO 会自动回滚。

    因此,根据您的应用程序,事务可能会被回滚(也许您有一个甚至会为您提交的某个地方的侦听器?)。在异常发生的地方附近进行显式回滚可能是个好主意。

    【讨论】:

    • 但是...如果您开始事务,进行一些插入和更新,然后使 ALTER TABLE 在大于 1 的行上失败,则默认操作是实际提交... MySQL 5.7。跨度>
    • 正确,MySQL DDL 查询(如 ALTER TABLE、CREATE TABLE 等)会创建隐式提交。 dev.mysql.com/doc/refman/5.7/en/implicit-commit.html
    • 从 PHP.net 页面,beginTransaction() 位于 try{...} 内部而不是外部。哪一个是正确的?在try{..} 内部还是之前?
    【解决方案2】:

    来自http://www.php.net/manual/en/pdo.transactions.php

    当脚本结束或连接即将关闭时,如果有未完成的事务,PDO 会自动回滚。 ...如果您没有明确提交事务,则假定出现问题,因此为了您的数据安全而执行回滚。

    尽管如此,在发生错误时显式回滚事务是一种很好的做法。有关详细信息,请参阅此问题:If an PHP PDO transaction fails, must I rollback() explicitely?

    【讨论】:

    • 感谢您提供的信息,事实上非常有趣并且正是我想要的。不知道我是如何在文档中错过它的。再次感谢。
    猜你喜欢
    • 2012-09-12
    • 2015-07-14
    • 2011-01-26
    • 1970-01-01
    • 2017-05-31
    • 2011-03-22
    • 1970-01-01
    • 2012-04-26
    • 1970-01-01
    相关资源
    最近更新 更多