[英]Rolling back MySQL queries
如果我在基于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 {
...
但是以上方法赋予更多机会使更多查询失败。 还有其他更有效的方法吗?
这就是我将如何使用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
}
更新
通常用户不关心,为什么他的操作失败。 如果查询失败,那绝不是用户的错。 这是开发人员或环境的错。 因此,没有理由根据哪个查询失败来呈现错误消息。
请注意,如果用户输入是失败查询的来源,则
但是-我不是说没有理由-我只是一无所知。 因此,如果您希望错误消息取决于哪个查询失败,则可以执行以下操作:
$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
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.