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

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

Примечание.

Если 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 все изменения в источнике данных, выполненные с помощью соединения, включаются в транзакцию. Передача значения NULL исключает соединение из прикрепления к текущей распределенной транзакции. Обратите внимание, что соединение должно быть открыто до вызова EnlistTransaction.

Примечание.

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

Внимание

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

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

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

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

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

См. также