System.Transactions.TransactionStatePSPEOperation.PromoteAndEnlistDurable C# (CSharp) Method

PromoteAndEnlistDurable() private method

private PromoteAndEnlistDurable ( InternalTransaction tx, System.Guid resourceManagerIdentifier, IPromotableSinglePhaseNotification promotableNotification, ISinglePhaseNotification enlistmentNotification, EnlistmentOptions enlistmentOptions, Transaction atomicTransaction ) : Enlistment
tx InternalTransaction
resourceManagerIdentifier System.Guid
promotableNotification IPromotableSinglePhaseNotification
enlistmentNotification ISinglePhaseNotification
enlistmentOptions EnlistmentOptions
atomicTransaction Transaction
return Enlistment
        internal override Enlistment PromoteAndEnlistDurable(
            InternalTransaction tx,
            Guid resourceManagerIdentifier,
            IPromotableSinglePhaseNotification promotableNotification,
            ISinglePhaseNotification enlistmentNotification,
            EnlistmentOptions enlistmentOptions,
            Transaction atomicTransaction
            )
        {
            // This call is only allowed if we have an outstanding call to ITransactionPromoter.Promote.
            if (!tx._attemptingPSPEPromote)
            {
                throw TransactionException.CreateTransactionStateException(tx._innerException, tx.DistributedTxId);
            }

            if (promotableNotification != tx._promoter)
            {
                throw TransactionException.CreateInvalidOperationException(
                        TraceSourceType.TraceSourceLtm,
                        SR.InvalidIPromotableSinglePhaseNotificationSpecified,
                        null,
                        tx.DistributedTxId
                        );
            }

            Enlistment enlistment;

            // First promote the transaction. We do this by simply changing the state of the transaction to Promoted.
            // In TransactionStateActive.EnlistPromotableSinglePhase, tx.durableEnlistment was set to point at the InternalEnlistment
            // for that PSPE enlistment. We are going to replace that with a "true" durable enlistment here. But we need to
            // set tx.durableEnlistment to null BEFORE we promote because if we don't the promotion will attempt to promote
            // the tx.durableEnlistment. Because we are doing the EnlistDurable AFTER promotion, it will be a "promoted"
            // durable enlistment and we can safely set tx.durableEnlistment to the InternalEnlistment of that Enlistment.
            tx._durableEnlistment = null;
            tx._promoteState = TransactionState.TransactionStatePromoted;
            tx._promoteState.EnterState(tx);

            // Now we need to create the durable enlistment that will replace the PSPE enlistment. Use the internalEnlistment of
            // this newly created durable enlistment as the tx.durableEnlistment.
            enlistment = tx.State.EnlistDurable(tx, resourceManagerIdentifier, enlistmentNotification, enlistmentOptions, atomicTransaction);
            tx._durableEnlistment = enlistment.InternalEnlistment;

            return enlistment;
        }