如果我在链上有多个查询,在基于IF的结构上,如下所示:
$query1 = mysqli_query("query here");
if(!query1){
//display error
} else {
$query2 = mysqli_query("another query here");
if(!query2){
//display error
//rollback the query1
} else {
query3 = mysqli_query("yet again another query");
if(!query3) {
//display error
//rollback the query2
//rollback the query1
} else {
query4 = mysqli_query("eh.. another one");
if(!query4){
//display error
//rollback the query3
//rollback the query2
//rollback the query1
} else {
return success;
}
}
}
}
如果下一个查询失败,是否有最好的方法来回滚上一个查询? 否则我将成功编辑数据库的前2个查询,但3°失败,因此3°和4°没有编辑dabatase,导致其被破坏。
我想到了类似的东西:
...
$query2 = mysqli_query("another query here");
if(!query2){
//display error
$rollback = mysqli_query("query to rollback query1");
} else {
query3 = mysqli_query("yet again another query");
if(!query3) {
//display error
$rollback = mysqli_query("query to rollback query2");
$rollback = mysqli_query("query to rollback query1");
} else {
...
但是上述方法更有可能使更多查询失败。 还有其他更有效的方法吗?
答案 0 :(得分:2)
这就是我使用mysqli
:
在查询失败时配置mysqli(在应用程序开始时的某些部分)抛出异常。
mysqli_report(MYSQLI_REPORT_STRICT);
这样您就不需要所有if .. elseif .. else
。
$connection->begin_transaction();
try {
$result1 = $connection->query("query 1");
// do something with $result1
$result2 = $connection->query("query 2");
// do something with $result2
$result3 = $connection->query("query 3");
// do something with $result3
// you will not get here if any of the queries fails
$connection->commit();
} catch (Exception $e) {
// if any of the queries fails, the following code will be executed
$connection->rollback(); // roll back everything to the point of begin_transaction()
// do other stuff to handle the error
}
<强>更新强>
通常用户不关心,为什么他的行动失败了。如果查询失败,那么用户从不会出错。它既是开发者的错,也是环境的错。因此,不应该根据哪个查询失败来呈现错误消息。
请注意,如果用户intput是失败查询的来源,那么
然而 - 我不能说不可能是原因 - 我根本就不知道。因此,如果您希望错误消息取决于哪个查询失败,您可以执行以下操作:
$error = null;
$connection->begin_transaction();
try {
try {
$result1 = $connection->query("query 1");
} catch (Exception $e) {
$error = 'query 1 failed';
throw $e;
}
// do something with $result1
try {
$result2 = $connection->query("query 2");
} catch (Exception $e) {
$error = 'query 2 failed';
throw $e;
}
// do something with $result2
// execute more queries the same way
$connection->commit();
} catch (Exception $e) {
$connection->rollback();
// use $error to find out which query failed
// do other stuff to handle the error
}