Распределенные транзакции

Область применения: .NET Framework .NET .NET Standard

Скачать ADO.NET

Транзакция - это набор связанных задач, который, помимо всего прочего, завершается успешно (фиксация) или с ошибкой (отмена) как единое целое. Распределенная транзакция — это транзакция, затрагивающая несколько ресурсов. Для фиксации распределенной транзакции все участники должны гарантировать, что любое изменение данных будет постоянным. Изменения должны сохраняться даже в случае фатального сбоя системы или других непредвиденных событий. Если хотя бы один из участников не сможет дать эту гарантию, вся транзакция завершится неудачей, а все изменения данных в рамках транзакции будут отменены.

Примечание.

Сведения о распределенных транзакциях в Базе данных SQL Azure и Управляемом экземпляре SQL Azure см. в статье Распределенные транзакции между облачными базами данных.

Работа с System.Transactions

В .NET управление распределенными транзакциями осуществляется с помощью API в пространстве имен System.Transactions. При участии нескольких постоянных диспетчеров ресурсов API-интерфейс System.Transactions делегирует обработку распределенной транзакции средству наблюдения за транзакциями, такому как координатор распределенных транзакций (Майкрософт) (MSDTC). Дополнительные сведения см. в разделе Основные сведения о транзакциях.

В ADO.NET 2.0 появилась поддержка включения в распределенную транзакцию с помощью метода EnlistTransaction, который включает подключение в экземпляр Transaction. В предыдущих версиях ADO.NET явное подключение к распределённым транзакциям выполнялось с помощью метода EnlistDistributedTransaction объекта подключения для включения соединения в экземпляр ITransaction, который поддерживается для обеспечения обратной совместимости. Дополнительные сведения о транзакциях в Enterprise Services см. в статье Взаимодействие с транзакциями Enterprise Services и COM+.

При использовании транзакции System.Transactions с поставщиком данных Microsoft SqlClient для SQL Server при работе с базой данных SQL Server автоматически используется облегчённая Transaction. Затем по мере необходимости транзакция может стать полной распределенной транзакцией. Дополнительные сведения см. в разделе Интеграция System.Transactions с SQL Server.

Автоматическое присоединение к распределенной транзакции

Автоматическое включение — это используемый по умолчанию (и предпочтительный) способ интеграции соединений ADO.NET с System.Transactions. Объект соединения автоматически присоединится к существующей распределенной транзакции, если он определит, что транзакция активна, что в терминах System.Transaction означает, что Transaction.Current не равно null. Автоматическое прикрепление транзакции происходит при открытии соединения. Это не произойдет после этого, даже если команда выполняется в пределах транзакции. Вы можете отключить автоматическое прикрепление для существующих транзакций, указав Enlist=false в качестве параметра строки подключения для SqlConnection.ConnectionString.

Включение в распределенную транзакцию вручную

Если автоматическое прикрепление отключено или требуется прикрепить транзакцию, которая была запущена после открытия подключения, вы можете выполнить прикрепление к существующей распределенной транзакции, используя метод EnlistTransaction объекта SqlConnection для поставщика данных Microsoft SqlClient для SQL Server. Прикрепление к существующей распределенной транзакции гарантирует, что в случае фиксации или отката транзакции изменения, выполненные кодом в источнике данных, будут также зафиксированы или откатаны назад.

Примечание.

Если DataReader запускается во время активной транзакции, то при попытке зафиксировать или выполнить откат транзакции возникнет исключение.

Участие в распределённых транзакциях особенно целесообразно при объединении бизнес-объектов в пул. Если объект бизнеса помещается в пул с открытым соединением, автоматическое включение в транзакцию происходит только при открытии этого соединения. При выполнении нескольких транзакций с помощью занесенного в пул бизнес-объекта открытое для этого объекта соединение не будет автоматически прикрепляться к новым транзакциям. В этом случае можно отключить для соединения автоматическое прикрепление транзакций и прикреплять его к транзакциям с помощью EnlistTransaction.

EnlistTransaction принимает один аргумент типа Transaction, который является ссылкой на существующую транзакцию. После вызова метода соединения EnlistTransaction все изменения в источнике данных, выполненные с помощью соединения, включаются в транзакцию. Передача значения null выводит соединение из участия в текущей распределенной транзакции. Обратите внимание, что соединение должно быть открыто до вызова EnlistTransaction.

Примечание.

После явного прикрепления соединения к транзакции нельзя отменить его прикрепление или прикрепить к другой транзакции до завершения первой транзакции.

Внимание

Если соединение уже запустило транзакцию с помощью метода соединений EnlistTransaction, то BeginTransaction вызовет исключение. Однако, если транзакция является локальной транзакцией и запускается в источнике данных (например, при явном выполнении оператора BEGIN TRANSACTION с использованием SqlCommand), EnlistTransaction выполнит откат локальной транзакции и подключится к существующей распределенной транзакции в соответствии с запросом. Вы не получите уведомление о том, что локальная транзакция была отменена, и должны самостоятельно управлять всеми локальными транзакциями, которые были запущены не с помощью BeginTransaction. При использовании поставщика данных Microsoft SqlClient для SQL Server при работе с SQL Server попытка включения в транзакцию вызовет исключение. Все остальные случаи останутся необнаруженными.

Продвигаемые транзакции в SQL Server

SQL Server поддерживает повышаемые транзакции, в которых локальная упрощенная транзакция может быть автоматически повышена до распределенной, если потребуется. Повышаемая транзакция не влечёт дополнительных издержек, связанных с распределённой транзакцией, если только эти дополнительные издержки не требуются. Дополнительные сведения и пример кода см. в разделе Интеграция System.Transactions с SQL Server.

Настройка распределенных транзакций

Для использования распределенных транзакций возможна необходимость включения в сети MS DTC. Если включен локальный брандмауэр Windows сервера, необходимо разрешить службе MS DTC использовать сеть или открыть порт MS DTC.