Оптимизация производительности с помощью механизмов уведомления об однофазной фиксации и повышаемого однофазного присоединения
В этом разделе описываются предоставляемые инфраструктурой System.Transactions механизмы для оптимизации производительности.
Повышаемое однофазное зачисление
Инфраструктура System.Transactions управляет транзакцией в пределах одного домена приложения, включающего по крайней мере один устойчивый ресурс или несколько неустойчивых ресурсов. Поскольку инфраструктура System.Transactions использует только вызовы внутри домена приложения, она обеспечивает оптимальную производительность.
Однако при предоставлении транзакции другому объекту в другом домене приложения (а также в другом процессе или компьютере) на том же самом компьютере или зачислении другого диспетчера устойчивых ресурсов инфраструктура System.Transactions автоматически передает управление транзакцией координатору MSDTC. Производительность транзакции, управляемой координатором MSDTC, является более низкой по сравнению с производительностью транзакции, управляемой инфраструктурой System.Transactions.
Для оптимизации производительности в инфраструктуре System.Transactions предусмотрен механизм повышаемого однофазного зачисления (PSPE), который позволяет одному удаленному устойчивому ресурсу, расположенному в другом домене приложения, процессе или компьютере, участвовать в транзакции System.Transactions, не вызывая ее повышения до транзакции MSDTC. Этот диспетчер ресурсов может "владеть" и управлять транзакцией, которая затем при необходимости может быть повышена до распределенной транзакции (или транзакции MSDTC). Это уменьшает вероятность использования координатора MSDTC.
Этот конкретный диспетчер ресурсов обычно имеет собственные внутренние не распределенные транзакции, и он должен поддерживать преобразование этих транзакций в распределенные транзакции во время выполнения. Например, в качестве такого диспетчера ресурсов может выступать SQL Server 2005. В этом случае инфраструктура System.Transactions принимает пассивное участие в управлении транзакцией, выполняя только мониторинг транзакции с целью определения необходимости ее передачи на следующий уровень иерархии. Для поддержки взаимодействия между инфраструктурой System.Transactions и диспетчером ресурсов последнему необходимо реализовать интерфейс IPromotableSinglePhaseNotification.
Метод EnlistPromotableSinglePhase используется для зачисления одного устойчивого ресурса, который затем может быть повышен. Этот метод обеспечивает возможность повышения зачисления по мере необходимости. В случае успешного зачисления диспетчер ресурсов создает собственную внутреннюю транзакцию и связывает ее с транзакцией System.Transactions. Если PSPE-зачисление выполнить не удается, диспетчеру ресурсов следует выполнить зачисление с помощью метода EnlistDurable. PSPE-зачисление может оказаться невозможным, если транзакция уже является распределенной или другой диспетчер ресурсов уже выполнил PSPE-зачисление.
После зачисления клиентские вызовы, предназначенные для фиксации или прерывания транзакции System.Transactions, преобразуются в вызовы диспетчера ресурсов посредством вызова метода SinglePhaseCommit или Rollback соответственно.
Если передача транзакции System.Transactions на следующий уровень иерархии не требуется, после фиксации транзакции диспетчер ресурсов получает уведомление SinglePhaseCommit. После этого он может зафиксировать изначально созданную внутреннюю транзакцию.
Если транзакцию System.Transactions требуется передать на следующий уровень иерархии (например, для поддержки нескольких диспетчеров ресурсов), инфраструктура System.Transactions информирует об этом диспетчер ресурсов путем вызова метода Promote интерфейса ITransactionPromoter, от которого наследуется интерфейс IPromotableSinglePhaseNotification. После этого диспетчер ресурсов осуществляет внутреннее преобразование локальной транзакции (для которой не требуется ведение журнала) в объект транзакции, способный участвовать в транзакции DTC, и связывает этот объект с уже выполненными действиями. В случае запроса фиксации транзакции диспетчер транзакций отправляет уведомление SinglePhaseCommit диспетчеру ресурсов, который фиксирует распределенную транзакцию, созданную во время передачи на следующий уровень иерархии.
Примечание.
Трассировки TransactionCommitted (создаваемые при вызове фиксации для эскалации транзакции) содержат идентификатор действия транзакции DTC.
Дополнительные сведения об эскалации управления см. в разделе "Эскалация управления транзакциями".
Сценарий передачи управления транзакцией на следующий уровень иерархии
На примере приведенного ниже сценария показано, как повысить транзакцию до распределенной транзакции, используя пространство имен System.Data как "посредника" для диспетчера ресурсов. В этом сценарии предполагается, что соединение System.Data, CN1, с базой данных уже участвует в транзакции и приложению необходимо включить в транзакцию второе соединение System.Data, CN2. Транзакция должна быть повышена до транзакции DTC, чтобы стать распределенной транзакцией с двухфазной фиксацией.
В этом сценарии:
Соединение CN1 вызывает метод EnlistPromotableSinglePhase для зачисления в транзакцию. Поскольку транзакция по-прежнему является локальной и других повышаемых зачислений нет, вызов метода EnlistPromotableSinglePhase является успешным.
Вызов метода EnlistPromotableSinglePhase вторым соединением, CN2, заканчивается неудачей, поскольку в транзакции уже используется другое повышаемое зачисление. Поэтому соединению CN2 необходимо получить транзакцию DTC, чтобы выполнить передачу в SQL. Для этого соединение использует один из методов, предоставляемых классом TransactionInterop, чтобы представить транзакцию в формате, подходящем для передачи в SQL.
System.Transactions вызывает метод Promote интерфейса ITransactionPromoter, реализуемого соединением CN1.
На этом этапе соединение CN1 передает транзакцию на следующий уровень иерархии с помощью механизма, характерного для SQL 2005 и System.Data.
Значение, возвращаемое методом Promote, представляет массив байтов, который содержит токен распространения для транзакции. System.Transactions использует этот маркер распространения для создания транзакции DTC, которую она может включить в локальную транзакцию.
На этом этапе соединение CN2 может использовать данные, полученные в результате вызова одного из методов объектом TransactionInterop, для передачи транзакции в SQL.
Теперь оба соединения зачислены в распределенную транзакцию DTC.
Оптимизация однофазной фиксации
Протокол однофазной фиксации эффективнее во время выполнения, так как все обновления выполняются без явной координации. Чтобы использовать данную оптимизацию, необходимо реализовать диспетчер ресурсов с помощью интерфейса ISinglePhaseNotification и зачислить его в транзакцию с помощью метода EnlistDurable или EnlistVolatile. В частности, параметр EnlistmentOptions должен иметь значение, чтобы None обеспечить выполнение единой фиксации этапа.
Интерфейс ISinglePhaseNotification наследуется от интерфейса IEnlistmentNotification, поэтому если реализованный диспетчер ресурсов не подходит для однофазной фиксации, он, тем не менее, может получать уведомления о двухфазной фиксации. Если реализованный диспетчер ресурсов получает уведомление SinglePhaseCommit от диспетчера транзакций, он должен попытаться выполнить действия, необходимые для фиксации транзакции, и сообщить диспетчеру транзакций о необходимости фиксации или отката транзакции путем вызова метода Committed, Aborted или InDoubt параметра SinglePhaseEnlistment. Ответ Done, переданный зачисленному ресурсу на данном этапе, подразумевает семантику ReadOnly. Поэтому не следует передавать ответ Done в дополнение к вызову любого из других методов.
Если существует только одна переменная и нет устойчивого зачисления, то переменная зачисления получает уведомление SPC. Если есть какие-либо переменные и только один устойчивый зачисление, переменные вложения получают 2PC. После этого зачисленный устойчивый ресурс получает уведомление об однофазной фиксации (SPC).