php中事务失败的恢复
SQL查询可能会由于多种原因而失败,即使同一查询以前运行了100次都没有问题。我想检测事务是否失败。我找到了两种方法: 1:使用大量if-else语句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();
$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您实际上可以自己测试它。尝试执行一个无效的查询,看看会发生什么。