php - PDO "all or nothing"删除事务

标签 php pdo transactions

我是 PDO 事务的新手,遇到以下情况:我想从两个单独的表中删除,条件是如果其中一个删除失败,则两者都不应该发生。这似乎是交易的理想场景。我尝试了以下方法:

$db->beginTransaction();

try {
    $db->exec( "DELETE FROM table1 WHERE galleryid = '$gallery_id' AND userid = '1'" );
    $db->exec( "DELETE FROM table2 WHERE galleryid = '$gallery_id'" );
    $db->commit();
} catch( PDOException $e ) {
    $db->rollBack();
    echo $e->getMessage();
}

在第一个删除查询中,我查询了一些不正确的内容(也就是说,table1 中没有 user_id 等于 1 的实例)。尽管如此,第二次删除还是通过了。这可能是预期的行为,我没有正确测试。

那么,我如何使用事务正确编写此代码,以便两个删除都通过或都不通过?

最佳答案

如果 DELETE 匹配零行,则不是失败或错误。

如果要测试 DELETE 影响了多少行,请使用 PDOStatement::rowCount() .

这是一个例子:

$db->beginTransaction();
try {
    $del1 = $db->prepare( "DELETE FROM table1 WHERE galleryid = :galleryid AND userid = :userid" );
    $del1->execute(array(":galleryid"=>$gallery_id, ":userid"=>1));
    if ($del1->rowCount() < 1) {
      throw new RuntimeException("Delete from table1 matched no rows.")
    }

    $del2 = $db->prepare( "DELETE FROM table2 WHERE galleryid = :galleryid" );
    $del2->execute(array(":galleryid"=>$gallery_id));
    if ($del2->rowCount() < 1) {
      throw new RuntimeException("Delete from table2 matched no rows.")
    }

    $db->commit();
} catch( RuntimeException $e ) {
    $db->rollBack();
    echo $e->getMessage();
}

回复你的评论:

这是交易的一个很好的应用。也就是说,您希望同时应用 table1 和 table2 的删除,并且不要让数据从一个表中删除而不从另一个表中删除。

如果其中任何一个都不匹配任何行,听起来您想中止这两个删除。我扩展了上面的代码示例以显示更完整的示例。如果该示例没有使用事务对两个更改进行分组,它可能允许第一次删除成功,然后发现第二次删除没有删除任何内容。

关于php - PDO "all or nothing"删除事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15369168/

相关文章:

php - 使用 PHP 将 Ai 转为 Png

php - 如何从给定的数字月份 PHP 获取该月的第一个和最后一个日期

php - SQL 查询不等于运算符不工作,使用 JOIN

PHP/PDO奇怪的请求

php - MySQL事务超时多久

mysql - 数据库触发器对于跨表完整性约束是否安全?

php - 如何检测 "5 in a row"游戏中的对角线获胜 (PHP)

php - FLASH、PHP、MySQL 连接

mysql - 什么更好 : joins or multiple sub-select statements as part of one query

database - ZF2 - 更新多个表的数据库事务