PHP PDO 事务自动回滚

Posted

技术标签:

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

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

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

【问题讨论】:

【参考方案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?

【讨论】:

感谢您提供的信息,事实上非常有趣并且正是我想要的。不知道我是如何在文档中错过它的。再次感谢。

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

PHP PDO事务回滚不起作用

PDO:事务不回滚?

PDO 中的事务在哪里回滚?

使用 PDO 自动提交

PHP PDO 基础知识

PHP PDO 在事务中创建多个表