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


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

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

Примечание.

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

Работа с System.Transactions

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

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

При использовании транзакции System.Transactions с поставщиком .NET Framework для SQL Server для базы данных SQL Server автоматически будет использована упрощенная Transaction. Затем по мере необходимости транзакция может стать полной распределенной транзакцией. Дополнительные сведения см. в статье System.Transactions Integration with SQL Server.

Примечание.

Максимальное количество распределенных транзакций, которое база данных Oracle может обрабатывать одновременно, по умолчанию равно 10. При соединении с базой данных Oracle после десятой транзакции возникает исключение. Oracle не поддерживает DDL в рамках распределенной транзакции.

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

Автоматическое подключение является способом по умолчанию (и предпочитаемым) для интеграции соединений ADO.NET с System.Transactions. Если объект соединения определяет, что транзакция активна, он автоматически присоединяется к существующей распределенной транзакции, что, в терминах System.Transaction, означает, что Transaction.Current не является NULL. Автоматическое прикрепление транзакции происходит при открытии соединения. Этого не произойдет после этого, даже если команда выполняется внутри контекста транзакции. Для отключения автоматического прикрепления в существующих транзакциях следует указать Enlist=false в качестве параметра строки соединения для SqlConnection.ConnectionString или OLE DB Services=-7 в качестве параметра строки соединения для OleDbConnection.ConnectionString. Дополнительные сведения о параметрах строки соединения Oracle и ODBC см. в OracleConnection.ConnectionString и OdbcConnection.ConnectionString.

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

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

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

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

Примечание.

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

Внимание

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

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

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

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

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

См. также