Vorgehensweise: Ausführen von Transaktionen
Der SQLSRV-Treiber des Microsoft-Treiber für PHP für SQL Server bietet drei Funktionen zur Durchführung von Transaktionen:
Der PDO_SQLSRV-Treiber bietet drei Funktionen zur Durchführung von Transaktionen:
Ein Beispiel hierzu finden Sie unter PDO::beginTransaction .
Im weiteren Verlauf dieses Themas wird erläutert und veranschaulicht, wie Sie Transaktionen mit dem SQLSRV-Treiber durchführen können.
Bemerkungen
Die Schritte zum Ausführen einer Transaktion können wie folgt zusammengefasst werden:
Starten Sie die Transaktion mit sqlsrv_begin_transaction.
Überprüfen Sie jede Abfrage, die Teil der Transaktion ist, auf Erfolg oder Fehlschlagen.
Committen Sie die Transaktion gegebenenfalls mit Sqlsrv_commit. Andernfalls können Sie mit sqlsrv_rollback. Nach dem Aufrufen von sqlsrv_commit oder sqlsrv_rollback wird der Treiber in den Autocommit-Modus zurückversetzt.
Microsoft-Treiber für PHP für SQL Server befindet sich standardmäßig im Autocommit-Modus. Dies bedeutet, dass alle Abfragen bei Erfolg automatisch committet werden, es sei denn, sie wurden durch sqlsrv_begin_transaction.
Wenn eine explizite Transaktion nicht mit sqlsrv_commit committet wird, wird beim Trennen der Verbindung oder bei der Beendigung des Skripts ein Rollback durchgeführt.
Verwenden Sie eingebettetes Transact-SQL nicht zum Durchführen von Transaktionen. Führen Sie z. B. keine Anweisung mit "BEGIN TRANSACTION" als Transact-SQL-Abfrage aus, um eine Transaktion zu beginnen. Das erwartete Transaktionsverhalten kann nicht garantiert werden, wenn Sie eingebettetes Transact-SQL zum Durchführen von Transaktionen verwenden.
Für die Durchführung von Transaktionen sollten die oben aufgelisteten sqlsrv -Funktionen verwendet werden.
Beispiel
BESCHREIBUNG
Im folgenden Beispiel werden mehrere Abfragen im Rahmen einer Transaktion ausgeführt. Wenn alle Abfragen erfolgreich sind, wird die Transaktion committet. Wenn eine der Abfragen fehlschlägt, wird für die Transaktion ein Rollback ausgeführt.
Das Beispiel versucht, einen Verkaufsauftrag aus der Sales.SalesOrderDetail -Tabelle zu löschen und die Lagerbestände der Produkte in der Product.ProductInventory -Tabelle für jedes Produkt im Verkaufsauftrag anzupassen. Diese Abfragen werden in eine Transaktion aufgenommen, weil alle Abfragen erfolgreich ausgeführt werden müssen, damit die Datenbank den Status der Aufträge und die Verfügbarkeit von Produkten korrekt widerspiegelt.
Die erste Abfrage im Beispiel ruft die Produkt-IDs und Mengen für eine bestimmte Verkaufsauftrags-ID ab. Diese Abfrage ist nicht Teil der Transaktion. Das Skript wird jedoch beendet, wenn diese Abfrage fehlschlägt, da die Produkt-IDs und Mengen zur Durchführung von Abfragen erforderlich sind, die Teil der nachfolgenden Transaktion sind.
Die anschließenden Abfragen (Löschen des Verkaufsauftrags und Aktualisieren der Lagerbestände der Produkte) sind Teil der Transaktion.
Das Beispiel setzt voraus, dass SQL Server und die AdventureWorks-Datenbank auf dem lokalen Computer installiert sind. Wenn das Beispiel über die Befehlszeile ausgeführt wird, werden alle Ausgaben in die Konsole geschrieben.
Code
<?php
/* Connect to the local server using Windows Authentication and
specify the AdventureWorks database as the database in use. */
$serverName = "(local)";
$connectionInfo = array( "Database"=>"AdventureWorks");
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if( $conn === false )
{
echo "Could not connect.\n";
die( print_r( sqlsrv_errors(), true));
}
/* Begin transaction. */
if( sqlsrv_begin_transaction($conn) === false )
{
echo "Could not begin transaction.\n";
die( print_r( sqlsrv_errors(), true));
}
/* Set the Order ID. */
$orderId = 43667;
/* Execute operations that are part of the transaction. Commit on
success, roll back on failure. */
if (perform_trans_ops($conn, $orderId))
{
//If commit fails, roll back the transaction.
if(sqlsrv_commit($conn))
{
echo "Transaction committed.\n";
}
else
{
echo "Commit failed - rolling back.\n";
sqlsrv_rollback($conn);
}
}
else
{
"Error in transaction operation - rolling back.\n";
sqlsrv_rollback($conn);
}
/*Free connection resources*/
sqlsrv_close( $conn);
/*---------------- FUNCTION: perform_trans_ops -----------------*/
function perform_trans_ops($conn, $orderId)
{
/* Define query to update inventory based on sales order info. */
$tsql1 = "UPDATE Production.ProductInventory
SET Quantity = Quantity + s.OrderQty
FROM Production.ProductInventory p
JOIN Sales.SalesOrderDetail s
ON s.ProductID = p.ProductID
WHERE s.SalesOrderID = ?";
/* Define the parameters array. */
$params = array($orderId);
/* Execute the UPDATE statement. Return false on failure. */
if( sqlsrv_query( $conn, $tsql1, $params) === false ) return false;
/* Delete the sales order. Return false on failure */
$tsql2 = "DELETE FROM Sales.SalesOrderDetail
WHERE SalesOrderID = ?";
if(sqlsrv_query( $conn, $tsql2, $params) === false ) return false;
/* Return true because all operations were successful. */
return true;
}
?>
Kommentare
Für die Überwachung des Transaktionsverhaltens ist eine empfohlene Fehlerbehandlung im vorherigen Beispiel nicht enthalten. Für Produktionsanwendungen wird empfohlen, dass jeder Aufruf einer sqlsrv-Funktion auf Fehler überprüft wird und eventuelle Fehler entsprechend behandelt werden.
Weitere Informationen
Aktualisieren von Daten (Microsoft-Treiber für PHP für SQL Server)