In PHP ist MySQLI_STMT :: Preparation eine Schlüsselmethode für Vorverarbeitungsanweisungen. Es kann die SQL -Injektion effektiv verhindern und die Ausführungseffizienz verbessern. Bei der Transaktionsverarbeitung begegnen Sie jedoch bei Verwendung von MySQLI_STMT :: Vorbereitung häufig auf einige Fallstricke, was dazu führt, dass Transaktionen nicht ordnungsgemäß einreichen oder rollen können, und sogar Datenkonsistenzen. Dieser Artikel wird diese gemeinsamen Fallstricke im Detail analysieren und entsprechende Lösungen bereitstellen.
Transaktion ist eine Reihe von Vorgängen in der Datenbankverwaltung, bei der diese Vorgänge entweder erfolgreich sind oder alle fehlschlagen. Unter Verwendung von MySQLIs Transaktionskontrolle wird die folgende Methode normalerweise aufgerufen:
$mysqli->begin_transaction();
$mysqli->commit();
$mysqli->rollback();
MySQLI_STMT :: Preparation bindet SQL -Anweisungen und Vorkompiles. Es wird korrekt verwendet, um sicherzustellen, dass die SQL -Erklärung legal ist und die gebundenen Parameter korrekt sind.
Pitspunkt : Nach dem Aufrufen von $ stmt = $ mysqli-> vorbereiten ($ sql); es wird nicht überprüft, ob $ stmt falsch ist. Wenn die Vorbereitung fehlschlägt, wenn SQL -Syntaxfehler oder andere Gründe weitergegeben werden, wird die Transaktion weiter ausgeführt, und nachfolgende Operationen können einen Fehler melden, was zu einer Transaktionsausnahme führt.
lösen :
$stmt = $mysqli->prepare($sql);
if ($stmt === false) {
$mysqli->rollback();
throw new Exception('Prepare failed: ' . $mysqli->error);
}
In einer Transaktion, wenn die Vorbereitung fehlschlägt, rollen Sie zurück und stoppen Sie die nachfolgenden Operationen.
Punkte : Manchmal führt der Entwickler $ STMT = $ mysqli-> vorbereiten ($ sql); Bevor Sie $ MySQLI-> begin_transaction () nennen;. Unter bestimmten MySQL -Versionen oder -konfigurationen werden jedoch automatisch implizit vorbereitet, was dazu führt, dass der Transaktionseffekt ungültig ist.
lösen :
Stellen Sie sicher, dass Sie zuerst die Transaktion starten und anschließend vorbereiten:
$mysqli->begin_transaction();
$stmt = $mysqli->prepare($sql);
// Anschließende Bindung und Ausführung
Punkte : Vorverarbeitungsanweisungen unterstützen nicht das Schreiben mehrerer SQL -Anweisungen gleichzeitig. Wenn $ SQL mehrere von Semikolons geteilte Anweisungen enthält, fällt die Vorbereitung aus.
lösen :
Stellen Sie sicher, dass jedes Mal nur eine einzelne SQL -Anweisung vorbereitet wird, und führen Sie bei Bedarf mehrere Anweisungen separat aus.
Pitpunkt : Parameterbindungsfehler wie Typ -Missverhältnis oder alle nicht gebundenen Platzhalter verursachen Ausführungsversagen und die Transaktion schlägt schließlich fehl.
lösen :
Stellen Sie sicher, dass der Typ und die Anzahl der gebundenen Parameter korrekt sind, z. B.:
$stmt->bind_param('si', $name, $id);
Und überprüfen Sie den Rückgabewert von bind_param .
Pitpunkt : Wenn $ stmt-> close () nicht vor dem Ende der Transaktion aufgerufen wird, kann die Verbindungsressource nicht freigegeben werden, was sich auf nachfolgende Transaktionsoperationen auswirkt.
lösen :
Bevor die Transaktion endet, rufen Sie $ stmt-> close () auf, um sicherzustellen, dass die Ressource rechtzeitig freigegeben wird.
Grubespunkt : Unkausorte Ausnahme oder Fehler, was dazu führt, dass die Transaktion nicht ordnungsgemäß festgelegt oder zurückgerollt wird.
lösen :
Verwenden Sie die Try-Catch-Struktur, um Transaktionen zurückzurufen, wenn Sie Ausnahmen erfassen:
try {
$mysqli->begin_transaction();
$stmt = $mysqli->prepare($sql);
if ($stmt === false) {
throw new Exception($mysqli->error);
}
$stmt->bind_param('si', $name, $id);
$stmt->execute();
$mysqli->commit();
} catch (Exception $e) {
$mysqli->rollback();
echo "Transaction failed: " . $e->getMessage();
}
<?php
$mysqli = new mysqli('gitbox.net', 'user', 'password', 'database');
if ($mysqli->connect_error) {
die('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
}
try {
$mysqli->begin_transaction();
$sql = "UPDATE users SET name = ? WHERE id = ?";
$stmt = $mysqli->prepare($sql);
if ($stmt === false) {
throw new Exception('Prepare failed: ' . $mysqli->error);
}
$name = 'Alice';
$id = 123;
if (!$stmt->bind_param('si', $name, $id)) {
throw new Exception('Bind param failed: ' . $stmt->error);
}
if (!$stmt->execute()) {
throw new Exception('Execute failed: ' . $stmt->error);
}
$stmt->close();
$mysqli->commit();
echo "Transaction succeeded.";
} catch (Exception $e) {
$mysqli->rollback();
echo "Transaction failed: " . $e->getMessage();
}
$mysqli->close();
?>
Führen Sie immer Vorbereitung nach dem Start der Transaktion aus.
Überprüfen Sie die Rückgabewerte von Preped , Bind_param und führen Sie aus .
Jeder erstellt nur eine einzige Aussage.
Achten Sie darauf, die Transaktion zurückzusetzen, wenn eine Ausnahme eintritt.
Schließen Sie die Vorverarbeitungs -Anweisung -Ressource.
Das Befolgen der oben genannten Spezifikationen kann häufige Fallstricke effektiv vermeiden, die bei der Verwendung von MySQLI_stmt :: in der Transaktionsverarbeitung vorbereitet werden , um die Datenkonsistenz und die Code -Robustheit sicherzustellen.