如何使用 try catch finally 识别 php mysqli 事务中哪个查询失败了

问题描述 投票:0回答:1

在 PHP MySQL 事务中执行多个准备好的查询时,如何识别哪个查询导致回滚?我想这样做是为了通过电子邮件向特定人员提供有意义的消息,因此我不想简单地发送异常响应。

我相信下面的代码片段(改编自here)使用更新和插入作为示例将执行两个查询或回滚它们。但是,在这个简单的示例中,有没有一种方法可以在 catch 块中放置两个 echo 语句,根据失败的查询(更新或插入)显示不同的消息?

<?php

$conn = mysqli_connect($servername, $username, $password, $dbname);  //connect to database
if (mysqli_connect_errno()) {      // Check connection
    log_message("Failed to connect to MySQL  " . mysqli_connect_error());
    exit();
}
try { //finally
    $stmt1 = $conn->prepare("UPDATE table1 SET f1 = 1 WHERE f2 = ? AND f3 = ?");
    $stmt2 = $conn->prepare("INSERT INTO table2 (f4,f5) VALUES (?,?)");
    $conn->begin_transaction();
    try {  // catch
        $stmt1->bind_param('iii', $data1, $data2, $data3); //bind parameters to update query
        $stmt1->execute();                               //execute update
        $stmt2->bind_param('ii', $data4, $data5);         //bind parameters to insert query
        $stmt2->execute();                               //execute insert
        $conn->commit();                                 //no errors, commit both queries
    } //end try catch
    catch (Exception $e) {                               //something went wrong
        $conn->rollback();
        echo "SQL error ".$e->getMessage();              //report error - but which query failed?
    }
}//try finally
finally {
    mysqli_close($conn);
}

注意:上面的代码是我的真实代码的修改版本(相当复杂),只是为了说明这个问题的要点并显示我真实代码的一般结构。如果您发现其中存在语法错误,请随时编辑它,而不是留下评论告诉我它不会按原样运行或者它不是我的真实代码

php mysqli transactions try-catch
1个回答
0
投票

您捕获的异常将包含文件名和发生异常的行。使用此信息您可以找出哪个语句失败了。

从 mysqli 获得的异常不包含所使用的 SQL 查询,因为该异常可能因多种不同原因而引发。它根本不一定是 SQL 的错误。您的事务可能会因与 SQL 无关的问题而回滚。因此,无法确定哪个 SQL 出了问题。

但这没关系。如果您想通知开发人员某个问题,您只需向他们发送异常以及完整的回溯即可。他们可以查看代码并找到发生异常的行号。无需将此信息发送给非开发人员的任何人。如果您想将其发送给数据库管理员,那就错了。首先,开发人员应该调查异常,因为它很可能是代码中的问题。如果他们认为这是数据库的问题,那么开发人员应该将事件转发给相关人员。但是,代码应该只告知开发人员该问题。

© www.soinside.com 2019 - 2024. All rights reserved.