我有一些查询到目前为止已完全运行,但我想将它们包装在一个事务中以减少数据损坏的可能性。运行代码后,所有外观都可以正常工作(即不会抛出异常),但查询永远不会提交给数据库。我已经查看了S.O.的其他问题。但我还没有发现任何适用于我的情况。
这是我的代码:
db::$pdo->beginTransaction(); // accesses PDO object method
try {
$sql = "INSERT INTO expenses SET date=:date, amount=:amount, accountId=:account; ";
$sql .= "UPDATE accounts SET balance = balance - :amount WHERE id = :account";
$s = db::$pdo->prepare($sql);
$s->bindValue(':date', $date);
$s->bindValue(':amount', $amount);
$s->bindValue(':account', $account);
$s->execute();
db::$pdo->commit();
echo 'success';
}
catch (PDOException $e) {
db::$pdo->rollback();
echo '<p>Failed: ' . $e->getMessage() . '</p>';
}
当我运行代码时,它输出成功消息,但就像我说的那样,没有任何东西被提交到数据库。
由于它是相关的,我还应该注意到我的PDO错误模式设置为ERRMODE_EXCEPTION
,所以我不认为导致问题的原因是什么。我正在运行MySQL数据库(InnoDB)
有什么想法吗?
答案 0 :(得分:1)
我不完全确定如何在单个查询语句中运行多个查询(如果它可以工作),因为我通常通过在prepare / execute语句中单独运行每个查询来执行事务。事务仍将排队所有更改,直到按预期提交/回滚。根据{{3}}它似乎有效,但是这个例子不是绑定值,所以这可能是另一个问题。
我建议将查询拆分为多个prepare / bind / execute语句,它应该按预期工作。
答案 1 :(得分:-1)
成功消息将始终显示,因为它只是在那里回显..如果你想只在执行后显示成功你应该使用if语句..对于不提交部分它可能是很多东西。你确定所有的价值都是$ date,$ amount,$ account?您也可以尝试从简单的插入开始,如果有效,请执行更新..
$sql = 'INSERT INTO expenses (date, amount, account)
VALUES(:date, :amount, :account)';
$stmt = $this->pdo->prepare($sql);
$stmt->bindValue(':date', $);
$stmt->bindValue(':amount', $amount);
$stmt->bindValue(':account', $account);
if($stmt->execute()) {
db::$pdo->commit();
echo 'success';
}
不确定db :: $ pdo-&gt; commit();部分因为我使用某种OOP方式,但希望这可能会有所帮助。
答案 2 :(得分:-1)
我认为我在其中一个项目中遇到了类似问题,请在您拥有的项目之后添加另一个catch块,以便代码看起来像:
catch (PDOException $e) {
db::$pdo->rollback();
echo '<p>Failed: ' . $e->getMessage() . '</p>';
}
catch (Exception $exc) {
db::$pdo->rollback();
echo '<p>Failed: ' . $exc->getMessage() . '</p>';
}
它将允许您捕获PDOException
以外的类的异常,因此您可以确保更多。
<强>更新强>
请考虑将两个查询拆分为2个PDO语句,如下所示:
$sql = "INSERT INTO expenses SET date=:date, amount=:amount, accountId=:account; ";
$s = db::$pdo->prepare($sql);
$s->bindValue(':date', $date);
$s->bindValue(':amount', $amount);
$s->bindValue(':account', $account);
$s->execute();
$sql2 = "UPDATE accounts SET balance = balance - :amount WHERE id = :account;";
$s2 = db::$pdo->prepare($sql2);
$s2->bindValue(':amount', $amount);
$s2->bindValue(':account', $account);
$s2->execute();
我在整个项目中使用这种方法取得了成功,所以我希望它可以提供帮助。
答案 3 :(得分:-2)
不要使用db::$pdo->commit();
使用
$sql = "INSERT INTO expenses SET date=:date, amount=:amount, accountId=:account;";
$sql .= "UPDATE accounts SET balance = balance - :amount WHERE id = :account;COMMIT;"; // change here
有点傻;(