在 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);
}
注意:上面的代码是我的真实代码的修改版本(相当复杂),只是为了说明这个问题的要点并显示我真实代码的一般结构。如果您发现其中存在语法错误,请随时编辑它,而不是留下评论告诉我它不会按原样运行或者它不是我的真实代码。
您捕获的异常将包含文件名和发生异常的行。使用此信息您可以找出哪个语句失败了。
从 mysqli 获得的异常不包含所使用的 SQL 查询,因为该异常可能因多种不同原因而引发。它根本不一定是 SQL 的错误。您的事务可能会因与 SQL 无关的问题而回滚。因此,无法确定哪个 SQL 出了问题。
但这没关系。如果您想通知开发人员某个问题,您只需向他们发送异常以及完整的回溯即可。他们可以查看代码并找到发生异常的行号。无需将此信息发送给非开发人员的任何人。如果您想将其发送给数据库管理员,那就错了。首先,开发人员应该调查异常,因为它很可能是代码中的问题。如果他们认为这是数据库的问题,那么开发人员应该将事件转发给相关人员。但是,代码应该只告知开发人员该问题。