如何:執行交易
Microsoft Drivers for PHP for SQL Server 的 SQLSRV 驅動程式提供三個函數來執行交易:
PDO_SQLSRV 驅動程式提供三個方法來執行交易:
如需範例,請參閱 PDO::beginTransaction 。
本主題的其餘部分說明並示範如何使用 SQLSRV 驅動程式來執行交易。
備註
執行交易的步驟可以摘要如下:
以 sqlsrv_begin_transaction開始交易。
檢查屬於交易的每個查詢成功或失敗。
如果適當,請以 sqlsrv_commit開始交易。 否則,請以 sqlsrv_rollback開始交易。 在呼叫 sqlsrv_commit 或 sqlsrv_rollback 之後,驅動程式會回到自動認可模式。
Microsoft Drivers for PHP for SQL Server 預設為自動認可模式。 這表示所有查詢都會在成功時自動進行認可,除非已使用 sqlsrv_begin_transaction開始交易。
如果明確交易不是以 sqlsrv_commit 來認可,它會在關閉連線或終止指令碼時復原。
請勿使用內嵌的 Transact-SQL 來執行交易。 例如,請勿執行以 "BEGIN TRANSACTION" 作為 Transact-SQL 查詢的陳述式,進而開始交易。 當您使用內嵌的 Transact-SQL 來執行交易時,無法保證預期的交易行為。
稍早所列的 Sqlsrv 函數應該用來執行交易。
範例
描述
以下範例會在交易期間執行數個查詢。 如果所有查詢都成功,就會認可交易。 如果其中一個查詢失敗,則會復原交易。
此範例會嘗試從 Sales.SalesOrderDetail 資料表刪除銷售訂單,並在銷售訂單中每項產品的 Product.ProductInventory 資料表中調整產品庫存量。 這些查詢會包含在交易中,因為對資料庫而言,所有查詢都必須成功,才能正確地反映訂單狀態和產品可用性。
範例中的第一個查詢會擷取指定之銷售訂單識別碼的產品識別碼和數量。 此查詢不是交易的一部分。 不過,如果此查詢因為完成屬於後續交易一部分的查詢需有產品識別碼和數量而失敗,則指令碼會結束。
這可確保查詢 (刪除銷售訂單和更新產品庫存量) 是交易的一部分。
此範例假設本機電腦上已安裝 SQL Server 和 AdventureWorks 資料庫。 從命令列執行範例時,所有輸出都會寫入至主控台。
程式碼
<?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;
}
?>
註解
為了將焦點放在交易行為上,上述範例中並未包含一些建議的錯誤處理方式。 對於生產應用程式,我們建議檢查任何對 sqlsrv 函式的呼叫是否有錯誤並予以處理。