我是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的实例)。尽管如此,第二次删除仍然存在。这可能是预期的行为,我没有正确测试。
那么,我如何才能正确地使用删除既可以执行也可以不执行?
答案 0 :(得分:3)
如果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中的删除,并且不要从一个表而不是另一个表中删除数据。
如果它们中的任何一个都没有匹配,听起来你想要中止两个删除。我已经扩展了上面的代码示例以显示更完整的示例。如果该示例未使用事务对这两个更改进行分组,则可能允许第一个删除成功,然后发现第二个删除不会删除任何内容。
答案 1 :(得分:3)
仅仅因为你的第一个查询影响了0行并不意味着它会引发异常,所以没有什么可以捕获的。我不确定您是否接受了这项工作,但您可能希望使用PDOStatement::rowCount()
来检查受DELETE
影响的行数。