Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
php中事务失败的恢复_Php_Mysqli - Fatal编程技术网

php中事务失败的恢复

php中事务失败的恢复,php,mysqli,Php,Mysqli,SQL查询可能会由于多种原因而失败,即使同一查询以前运行了100次都没有问题。我想检测事务是否失败。我找到了两种方法: 1:使用大量if-else语句 $mysqli->begin_transaction(); $stmt = $mysqli->prepare("INSERT INTO testtable VALUES (?,?,?)"); if ( false===$stmt ) { $mysqli->rollback(); issueInternalError();

SQL查询可能会由于多种原因而失败,即使同一查询以前运行了100次都没有问题。我想检测事务是否失败。我找到了两种方法:

1:使用大量if-else语句

$mysqli->begin_transaction();
$stmt = $mysqli->prepare("INSERT INTO testtable VALUES (?,?,?)");
if ( false===$stmt ) {
  $mysqli->rollback();
  issueInternalError();
}

$rc = $stmt->bind_param('iii', $x, $y, $z);
if ( false===$rc ) {
  $mysqli->rollback();
  issueInternalError();
}
$rc = $stmt->execute();
if ( false===$rc ) {
  $mysqli->rollback();
  issueInternalError();
}else{
$mysqli->commit();
}

$stmt->close();
2:在try-catch块中执行查询

try{
    $mysqli->begin_transaction();
    $stmt = $mysqli->prepare("INSERT INTO testtable VALUES (?,?,?)");
    $stmt->bind_param('iii', $x, $y, $z);
    $stmt->execute();
    $mysqli->commit();

}catch(Exception $e){
    $mysqli->rollback();
    issueInternalError();
}
使用try/catch可以将代码减半,使其真正可读,但第二个代码是否能够正确捕获所有可能的错误?如果存在错误,issueInternalError将始终执行吗

更新:

我已将此代码添加到php文件的开头

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
我的测试结果好坏参半:

成功捕获此类错误:

    $mysqli->begin_transaction();
    $stmt = $mysqli->prepare("INSERT INTO testtable VALUES (?,?,?)");
    $stmt->bind_param('iiissss', $x, $y, $z); //error here is successfully catched
但事实并非如此

    $mysqli->begin_transaction();
    $stmt = $mysqli->prepare("INSERT INTO testtable VALUES (?,?,?)");
    $stmt->bind_param('iii', $x, $y, $z,""); //error not catched

看起来第二个不是由mysqli引起的,因此它不会被抛出

您的try-catch不会捕获所有错误。它只捕获异常。PHP中的错误和异常是有区别的

以下try-catch将仅捕获异常:

try {
    // ...
} catch(Exception $e) {
    // ...
}
要捕获异常和错误,可以使用Throwable接口。作为旁注,最好始终为PHP中的类和接口提供完全指定的名称

try {
    // ...
} catch(\Throwable $e) {
    // ...
}
Mysqli可以抛出异常和错误。当mysqli无法处理命令或在MySQL服务器端执行命令失败时,通常会触发异常。这些异常是mysqli\u sql\u异常类的实例

如果PHP端存在程序员错误,例如参数数量不正确或参数无效,那么mysqli将触发PHP错误。这些错误可以是各种各样的,但通常都是从基类错误派生的


警告:在PHP8之前,许多错误只是警告。这些已经被正确地分类了。此外,mysqli中还修复了一些软件错误,这些错误在出现异常时不会触发异常。为了获得最佳效果,请使用最新的PHP版本。

只要您记得,就可以了。我想我把我的问题弄糊涂了。我不担心SQL注入,而是确定事务是否成功。@sanjihan您实际上可以自己测试它。尝试执行一个无效的查询,看看会发生什么。