【问题标题】:Pdo Transaction does not roll back when while DELETE did not execute当 DELETE 未执行时,Pdo 事务不回滚
【发布时间】:2017-04-10 15:48:13
【问题描述】:

我正在构建一个应用程序,它应该执行涉及插入、删除和更新命令的多个查询。没有语法错误,但我发现删除命令没有删除条目,但插入命令插入了行并且操作没有回滚。如果删除动作没有发生,insert 和其他应该被取消是期望的结果。


<?
try {  
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->beginTransaction();
 $D = 2;
 $Dn = 3;

$dumpi = $pdo->prepare("INSERT INTO `dumpi` .... SELECT .... FROM .... ");
$dumpi->execute();

$matchi = $pdo->prepare("DELETE FROM `marchi` WHERE `id`=....");
$matchi->execute();

$usri = $pdo->prepare("UPDATE `users` SET `status`='0' WHERE `id`='$Dn' ");
$usri->execute();

$donati = $pdo->prepare("UPDATE `dnsn` SET `status`='d' WHERE `id`='$D' ");
$donati->execute();

$donatidel = $pdo->prepare("UPDATE `dnsn` SET `status`='d',`deleted_by`='m' WHERE `dn`='$Dn' AND `status`='1' ");
$donatidel->execute();

 $navwal = $pdo->prepare("UPDATE `wlt` SET `status`='0' WHERE `user`='$Dn'");
$navwal->execute();   

   $navwalt = $pdo->prepare("UPDATE `wlt` SET `status`='0' WHERE `dn`='$Dn' ");
 $navwalt->execute(); 
 // dont let te $D and Dn confuse you, its not the one causing any error

$pdo->commit();

 // echo 'it works';
} catch (PDOException $e) {
$pdo->rollBack();
echo "Failed: " . $e->getMessage();
 }
 ?>

代码到此结束... 我与 Db 的连接是这里的脚本...(刚刚为 ref.php7 添加)

$pdoOptions = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => true);
 try {
 $pdo = new PDO(
"mysql:host=" . MYSQL_HOST . ";dbname=" . MYSQL_DATABASE, //DSN
MYSQL_USER, //Username
MYSQL_PASSWORD, //Password
$pdoOptions //Options
);} catch (Exception $e) {
 // design this well to make sense
 die(
// conmment out in launch
$e->getMessage())


);
}

【问题讨论】:

  • 1.执行任何删除时是否出现任何错误?如果不是,那么回滚任何东西都没有意义。 2. 这样使用prepared statements是没有意义的,你的代码仍然容易受到sql注入攻击,并且会更慢并且消耗更多的内存。

标签: php mysql pdo transactions


【解决方案1】:

好吧,如果查询没有找到任何数据,这不是错误。

如果删除查询必须找到要删除的记录对您很重要,那么您必须手动验证,而不是抛出异常。

$stmt = $pdo->prepare("DELETE FROM `marchi` WHERE `id`=?");
$stmt->execute([....]);
if (!$stmt->rowCount())
{
    throw new Exception("Delete didn't find a record")
}

然后捕获异常,而不是 PDOException。

请注意,由于某些原因,您应该使用预准备语句

【讨论】:

  • 请注意,由于某种原因,您没有使用准备好的语句,而您应该这样做:我不明白——以及为什么我不应该捕获 PDOException。
猜你喜欢
  • 2017-05-31
  • 2011-01-26
  • 2015-11-15
  • 2015-07-14
  • 1970-01-01
  • 2017-09-21
  • 2012-07-15
  • 2013-05-13
  • 2019-05-08
相关资源
最近更新 更多