SQL Server Driver for PHP는 트랜잭션 수행을 위해 다음 세 가지 함수를 제공합니다.
이 항목에서는 이러한 함수를 사용하여 트랜잭션을 수행하는 방법에 대해 설명합니다.
트랜잭션 실행 단계는 다음과 같이 요약할 수 있습니다.
- 트랜잭션의 일부인 모든 쿼리 앞에 sqlsrv_begin_transaction을 배치합니다.
- 트랜잭션의 일부인 각 쿼리의 성공 또는 실패 여부를 확인합니다.
- 필요한 경우 sqlsrv_commit을 사용하여 트랜잭션을 커밋합니다. 그렇지 않으면 sqlsrv_rollback을 사용하여 트랜잭션을 롤백합니다. sqlsrv_commit 또는 sqlsrv_rollback을 호출한 후에는 드라이버가 자동 커밋 모드로 돌아갑니다.
참고
기본적으로 SQL Server Driver for PHP는 자동 커밋 모드로 설정됩니다. 즉, sqlsrv_begin_transaction을 사용하여 명시적 트랜잭션의 일부로 지정하지 않은 모든 쿼리는 성공 시 자동으로 커밋됩니다
참고
명시적 트랜잭션은 sqlsrv_commit을 사용하여 커밋하지 않으면 연결을 닫거나 스크립트를 종료할 때 롤백됩니다.
참고
포함된 Transact-SQL을 사용하여 트랜잭션을 수행하지 마십시오. 예를 들어, "BEGIN TRANSACTION"이 포함된 문을 Transact-SQL 쿼리로 실행하여 트랜잭션을 시작하지 마십시오. 포함된 Transact-SQL을 사용하여 트랜잭션을 수행할 경우 트랜잭션 동작이 예상대로 나타나지 않을 수 있습니다.
위에 나열된 sqlsrv 함수를 사용하여 트랜잭션을 수행해야 합니다.예
다음 예제에서는 여러 개의 쿼리를 트랜잭션의 일부로 실행합니다. 모든 쿼리가 성공적으로 실행되면 트랜잭션이 커밋됩니다. 쿼리 중 하나라도 실패하면 트랜잭션이 롤백됩니다.
이 예제에서는 Sales.SalesOrderDetail 테이블에서 판매 주문을 삭제하고 판매 주문의 각 제품에 대해 Product.ProductInventory 테이블에서 제품 재고 수준을 조정합니다. 주문 상태 및 제품 재고 유무를 데이터베이스에 정확하게 반영하려면 모든 쿼리가 성공해야 하므로 이 쿼리가 모두 트랜잭션에 포함됩니다.
이 예제의 첫 번째 쿼리는 지정된 판매 주문 ID에 대한 제품 ID와 수량을 검색합니다. 이 쿼리는 트랜잭션의 일부분이 아닙니다. 그러나 이후 트랜잭션의 일부인 쿼리를 완료하려면 제품 ID와 수량이 필요하기 때문에 이 쿼리가 실패하면 스크립트가 끝납니다.
이후 쿼리(판매 주문 삭제 및 제품 재고 수량 업데이트)는 트랜잭션의 일부입니다.
이 예제에서는 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 함수를 호출할 때 오류를 확인하여 적절히 처리하는 것이 좋습니다.