Php 我的PDO交易没有';不承诺,但也不承诺';不要抛出任何异常

Php 我的PDO交易没有';不承诺,但也不承诺';不要抛出任何异常,php,mysql,pdo,Php,Mysql,Pdo,我有一些查询到目前为止运行得很好,但我想将它们封装在事务中以降低数据损坏的可能性。在运行代码之后,一切看起来都正常(即没有抛出异常),但查询永远不会提交到数据库。我已经研究了S.O.的其他问题,但我没有发现任何适用于我的案例的问题 这是我的密码: db::$pdo->beginTransaction(); // accesses PDO object method try { $sql = "INSERT INTO expenses SET date=

我有一些查询到目前为止运行得很好,但我想将它们封装在事务中以降低数据损坏的可能性。在运行代码之后,一切看起来都正常(即没有抛出异常),但查询永远不会提交到数据库。我已经研究了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>';
    }
db::$pdo->beginTransaction();//访问PDO对象方法
试一试{
$sql=“插入费用设置日期=:日期,金额=:金额,账户ID=:账户;”;
$sql.=“更新帐户设置余额=余额-:金额,其中id=:帐户”;
$s=db::$pdo->prepare($sql);
$s->bindValue(':date',$date);
$s->bindValue(':amount',$amount);
$s->bindValue(':account',$account);
$s->execute();
db::$pdo->commit();
呼应"成功",;
}
捕获(PDO$e){
db::$pdo->rollback();
回显“失败:”。$e->getMessage()。

”; }
当我运行代码时,它会输出成功消息,但正如我所说的,没有任何内容提交到数据库

因为这是相关的,我还应该注意,我的PDO错误模式被设置为
ERRMODE\u EXCEPTION
,所以我不认为这是导致问题的原因。我正在运行一个MySQL数据库(InnoDB)


有什么想法吗?

成功消息会一直显示出来,因为它只是在那里回响。。如果希望仅在执行后显示成功,则应使用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';
        }    

不确定数据库::$pdo->commit();部分原因是我使用了某种面向对象的方式,但希望这能有所帮助

我想我在其中一个项目中遇到了类似的问题,请在您拥有的catch块之后添加另一个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>';
}

我在整个项目中成功地使用了这种方法,所以我希望它能有所帮助。

不要使用
db::$pdo->commit()

使用


有点傻;(

我不完全确定在一条查询语句中运行多个查询是如何工作的(如果可以的话)因为我通常通过在prepare/execute语句中分别运行每个查询来执行事务。在提交/回滚之前,事务仍会将所有更改按预期进行排队。根据它看来是可行的,但是示例中没有绑定值,因此这可能是另一个问题


我建议将查询拆分为多个prepare/bind/execute语句,它应该会按预期工作。

只是一个简单的尝试,但尝试单独运行查询,看看是否有效。如果插入成功,但更新失败,则插入和更新将导致数据损坏。这就是Transaction如果存在PDO以外的异常,它仍应抛出错误(并且不回显“成功”消息)。我尝试过,但仍然没有成功。这成功了。在一条语句中运行多个查询可以正常工作,除非您将它们包装到事务中,在这种情况下,事务由于某种原因无法提交。将它们拆分为单独的prepare/execute语句非常有效。仅在一条语句中运行多个查询如果您使用的是模拟的准备语句而不是正确的准备语句,则“很好”。您真的应该这样做。@PeeHaa我在链接的答案中看到了这一点。根据这一点,虽然默认情况下它是打开的。OP没有禁用它们(至少这里没有)因此,我假设他们的代码应该可以工作,如链接答案中的第二个示例所示。我的观点是OP应该更改它,因为默认值不好。使用模拟的预处理语句为可能的安全漏洞打开了大门。@PeeHaa同意,但我只是想知道它是否/为什么不工作。但我想这一点是没有意义的如果你认为它是坏的,不应该被这样使用。这表明你的数据库库中有一个错误——如果提交调用没有被翻译成数据库提交,那就有非常严重的错误。
$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();
$sql = "INSERT INTO expenses SET date=:date, amount=:amount, accountId=:account;";

$sql .= "UPDATE accounts SET balance = balance - :amount WHERE id = :account;COMMIT;";  // change here