我是 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/