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


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

Применимо: платформа .NET Framework .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.

См. также