我的PDO事务没有提交,但也没有抛出任何异常

时间:2014-12-31 00:06:16

标签: php mysql pdo

我有一些查询到目前为止已完全运行,但我想将它们包装在一个事务中以减少数据损坏的可能性。运行代码后,所有外观都可以正常工作(即不会抛出异常),但查询永远不会提交给数据库。我已经查看了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)

有什么想法吗?

4 个答案:

答案 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

有点傻;(