Поделиться через


Практическое руководство. Выполнение транзакций

Скачать драйвер PHP

Драйвер SQLSRV Драйверы Microsoft SQL Server для PHP предоставляет три функции для выполнения транзакций:

Драйвер PDO_SQLSRV предоставляет три метода для выполнения транзакций.

Пример см. в статье PDO::beginTransaction .

В оставшейся части этой статьи объясняется и демонстрируется, как использовать драйвер SQLSRV для выполнения транзакций.

Remarks

Шаги по выполнению транзакции можно обобщить следующим образом.

  1. Начните транзакцию с помощью sqlsrv_begin_transaction.

  2. Проверьте состояние выполнения каждого запроса, входящего в состав транзакции.

  3. При необходимости зафиксируйте транзакцию с помощью sqlsrv_commit. В противном случае выполните откат транзакции с помощью sqlsrv_rollback. После вызова sqlsrv_commit или sqlsrv_rollback драйвер возвращается в режим автофиксации.

    Драйверы Драйверы Microsoft SQL Server для PHP находятся в режиме автофиксации по умолчанию. Это означает, что все запросы автоматически фиксируются после успешного выполнения, если только они не были обозначены как часть явной транзакции с помощью 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 на наличие ошибок и обрабатывать их соответствующим образом.

См. также:

Обновление данных (драйверы Майкрософт для PHP для SQL Server)

Транзакции (ядро СУБД)

Информация о примерах кода в документации