Beispiel #1
0
        /// <summary>
        /// Gets the PromotedToken for the transaction.
        ///
        /// If the transaction has not already been promoted, retrieving this value will cause promotion. Before retrieving the
        /// PromotedToken, the Transaction.PromoterType value should be checked to see if it is a promoter type (Guid) that the
        /// caller understands. If the caller does not recognize the PromoterType value, retreiving the PromotedToken doesn't
        /// have much value because the caller doesn't know how to utilize it. But if the PromoterType is recognized, the
        /// caller should know how to utilize the PromotedToken to communicate with the promoting distributed transaction
        /// coordinator to enlist on the distributed transaction.
        ///
        /// If the value of a transaction's PromoterType is TransactionInterop.PromoterTypeDtc, then that transaction's
        /// PromotedToken will be an MSDTC-based TransmitterPropagationToken.
        /// </summary>
        /// <returns>
        /// The byte[] that can be used to enlist with the distributed transaction coordinator used to promote the transaction.
        /// The format of the byte[] depends upon the value of Transaction.PromoterType.
        /// </returns>
        public byte[] GetPromotedToken()
        {
            // We need to ask the current transaction state for the PromotedToken because depending on the state
            // we may need to induce a promotion.
            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceLtm, this);
            }

            if (Disposed)
            {
                throw new ObjectDisposedException(nameof(Transaction));
            }

            // We always make a copy of the promotedToken stored in the internal transaction.
            byte[] internalPromotedToken;
            lock (_internalTransaction)
            {
                internalPromotedToken = _internalTransaction.State.PromotedToken(_internalTransaction);
            }

            byte[] toReturn = new byte[internalPromotedToken.Length];
            Array.Copy(internalPromotedToken, toReturn, toReturn.Length);
            return(toReturn);
        }
Beispiel #2
0
        public void Rollback(Exception e)
        {
            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceLtm, this);
                etwLog.TransactionRollback(this, "Transaction");
            }

            if (Disposed)
            {
                throw new ObjectDisposedException(nameof(Transaction));
            }

            lock (_internalTransaction)
            {
                Debug.Assert(_internalTransaction.State != null);
                _internalTransaction.State.Rollback(_internalTransaction, e);
            }

            if (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceLtm, this);
            }
        }
        public static byte[] GetExportCookie(Transaction transaction, byte[] whereabouts)
        {
            if (null == transaction)
            {
                throw new ArgumentNullException(nameof(transaction));
            }

            if (null == whereabouts)
            {
                throw new ArgumentNullException(nameof(whereabouts));
            }

            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceDistributed, "TransactionInterop.GetExportCookie");
            }

            // Copy the whereabouts so that it cannot be modified later.
            var whereaboutsCopy = new byte[whereabouts.Length];

            Buffer.BlockCopy(whereabouts, 0, whereaboutsCopy, 0, whereabouts.Length);

            DistributedTransaction dTx = ConvertToDistributedTransaction(transaction);

            byte[] cookie = dTx.GetExportCookie(whereaboutsCopy);

            if (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceDistributed, "TransactionInterop.GetExportCookie");
            }

            return(cookie);
        }
        public static byte[] GetTransmitterPropagationToken(Transaction transaction)
        {
            if (null == transaction)
            {
                throw new ArgumentNullException(nameof(transaction));
            }

            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceDistributed, "TransactionInterop.GetTransmitterPropagationToken");
            }

            DistributedTransaction dTx = ConvertToDistributedTransaction(transaction);

            byte[] token = dTx.GetTransmitterPropagationToken();

            if (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceDistributed, "TransactionInterop.GetTransmitterPropagationToken");
            }

            return(token);
        }
        public IAsyncResult BeginCommit(AsyncCallback?asyncCallback, object?asyncState)
        {
            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceLtm, this);
                etwLog.TransactionCommit(TraceSourceType.TraceSourceLtm, TransactionTraceId, "CommittableTransaction");
            }

            ObjectDisposedException.ThrowIf(Disposed, this);

            lock (_internalTransaction)
            {
                if (_complete)
                {
                    throw TransactionException.CreateTransactionCompletedException(DistributedTxId);
                }

                Debug.Assert(_internalTransaction.State != null);
                // this.complete will get set to true when the transaction enters a state that is
                // beyond Phase0.
                _internalTransaction.State.BeginCommit(_internalTransaction, true, asyncCallback, asyncState);
            }

            if (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceLtm, this);
            }

            return(this);
        }
        public void EndCommit(IAsyncResult asyncResult)
        {
            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceLtm, this);
            }

            if (asyncResult != ((object)this))
            {
                throw new ArgumentException(SR.BadAsyncResult, nameof(asyncResult));
            }

            lock (_internalTransaction)
            {
                do
                {
                    Debug.Assert(_internalTransaction.State != null);
                    if (_internalTransaction.State.IsCompleted(_internalTransaction))
                    {
                        break;
                    }
                } while (Monitor.Wait(_internalTransaction));

                _internalTransaction.State.EndCommit(_internalTransaction);
            }

            if (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceLtm, this);
            }
        }
Beispiel #7
0
        public TransactionScope(
            Transaction transactionToUse,
            TimeSpan scopeTimeout,
            EnterpriseServicesInteropOption interopOption
            )
        {
            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceBase, this);
            }

            ValidateInteropOption(interopOption);
            _interopOption = interopOption;

            Initialize(
                transactionToUse,
                scopeTimeout,
                true);

            if (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceBase, this);
            }
        }
Beispiel #8
0
        public Enlistment PromoteAndEnlistDurable(Guid resourceManagerIdentifier,
                                                  IPromotableSinglePhaseNotification promotableNotification,
                                                  ISinglePhaseNotification enlistmentNotification,
                                                  EnlistmentOptions enlistmentOptions)
        {
            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceDistributed, this);
            }

            if (Disposed)
            {
                throw new ObjectDisposedException(nameof(Transaction));
            }

            if (resourceManagerIdentifier == Guid.Empty)
            {
                throw new ArgumentException(SR.BadResourceManagerId, nameof(resourceManagerIdentifier));
            }

            if (promotableNotification == null)
            {
                throw new ArgumentNullException(nameof(promotableNotification));
            }

            if (enlistmentNotification == null)
            {
                throw new ArgumentNullException(nameof(enlistmentNotification));
            }

            if (enlistmentOptions != EnlistmentOptions.None && enlistmentOptions != EnlistmentOptions.EnlistDuringPrepareRequired)
            {
                throw new ArgumentOutOfRangeException(nameof(enlistmentOptions));
            }

            if (_complete)
            {
                throw TransactionException.CreateTransactionCompletedException(DistributedTxId);
            }

            lock (_internalTransaction)
            {
                Debug.Assert(_internalTransaction.State != null);
                Enlistment enlistment = _internalTransaction.State.PromoteAndEnlistDurable(_internalTransaction,
                                                                                           resourceManagerIdentifier, promotableNotification, enlistmentNotification, enlistmentOptions, this);

                if (etwLog.IsEnabled())
                {
                    etwLog.MethodExit(TraceSourceType.TraceSourceDistributed, this);
                }

                return(enlistment);
            }
        }
Beispiel #9
0
        public static Transaction GetTransactionFromExportCookie(byte[] cookie)
        {
            if (null == cookie)
            {
                throw new ArgumentNullException(nameof(cookie));
            }

            if (cookie.Length < 32)
            {
                throw new ArgumentException(SR.InvalidArgument, nameof(cookie));
            }

            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceDistributed, "TransactionInterop.GetTransactionFromExportCookie");
            }

            var cookieCopy = new byte[cookie.Length];

            Buffer.BlockCopy(cookie, 0, cookieCopy, 0, cookie.Length);
            cookie = cookieCopy;

            // Extract the transaction guid from the propagation token to see if we already have a
            // transaction object for the transaction.
            // In a cookie, the transaction guid is preceeded by a signature guid.
            var txId = new Guid(cookie.AsSpan(16, 16));

            // First check to see if there is a promoted LTM transaction with the same ID.  If there
            // is, just return that.
            Transaction transaction = TransactionManager.FindPromotedTransaction(txId);

            if (transaction != null)
            {
                if (etwLog.IsEnabled())
                {
                    etwLog.MethodExit(TraceSourceType.TraceSourceDistributed, "TransactionInterop.GetTransactionFromExportCookie");
                }

                return(transaction);
            }

            // Find or create the promoted transaction.
            DistributedTransaction dTx = DistributedTransactionManager.GetTransactionFromExportCookie(cookieCopy, txId);

            transaction = TransactionManager.FindOrCreatePromotedTransaction(txId, dTx);

            if (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceDistributed, "TransactionInterop.GetTransactionFromExportCookie");
            }

            return(transaction);
        }
        public static Transaction GetTransactionFromTransmitterPropagationToken(byte[] propagationToken)
        {
            if (null == propagationToken)
            {
                throw new ArgumentNullException(nameof(propagationToken));
            }

            if (propagationToken.Length < 24)
            {
                throw new ArgumentException(SR.InvalidArgument, nameof(propagationToken));
            }

            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceDistributed, "TransactionInterop.GetTransactionFromTransmitterPropagationToken");
            }

            // Extract the transaction guid from the propagation token to see if we already have a
            // transaction object for the transaction.
            byte[] guidByteArray = new byte[16];
            for (int i = 0; i < guidByteArray.Length; i++)
            {
                // In a propagation token, the transaction guid is preceeded by two version DWORDs.
                guidByteArray[i] = propagationToken[i + 8];
            }

            var txId = new Guid(guidByteArray);

            // First check to see if there is a promoted LTM transaction with the same ID.  If there is, just return that.
            Transaction tx = TransactionManager.FindPromotedTransaction(txId);

            if (null != tx)
            {
                if (etwLog.IsEnabled())
                {
                    etwLog.MethodExit(TraceSourceType.TraceSourceDistributed, "TransactionInterop.GetTransactionFromTransmitterPropagationToken");
                }

                return(tx);
            }

            DistributedTransaction dTx = GetDistributedTransactionFromTransmitterPropagationToken(propagationToken);

            // If a transaction is found then FindOrCreate will Dispose the distributed transaction created.
            Transaction returnValue = TransactionManager.FindOrCreatePromotedTransaction(txId, dTx);

            if (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceDistributed, "TransactionInterop.GetTransactionFromTransmitterPropagationToken");
            }
            return(returnValue);
        }
Beispiel #11
0
        public TransactionScope(
            TransactionScopeOption scopeOption,
            TransactionScopeAsyncFlowOption asyncFlowOption
            )
        {
            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceBase, this);
            }

            ValidateAndSetAsyncFlowOption(asyncFlowOption);

            if (NeedToCreateTransaction(scopeOption))
            {
                _committableTransaction = new CommittableTransaction();
                _expectedCurrent        = _committableTransaction.Clone();
            }

            if (null == _expectedCurrent)
            {
                if (etwLog.IsEnabled())
                {
                    etwLog.TransactionScopeCreated(TransactionTraceIdentifier.Empty, TransactionScopeResult.NoTransaction);
                }
            }
            else
            {
                TransactionScopeResult scopeResult;

                if (null == _committableTransaction)
                {
                    scopeResult = TransactionScopeResult.UsingExistingCurrent;
                }
                else
                {
                    scopeResult = TransactionScopeResult.CreatedTransaction;
                }

                if (etwLog.IsEnabled())
                {
                    etwLog.TransactionScopeCreated(_expectedCurrent.TransactionTraceId, scopeResult);
                }
            }

            PushScope();

            if (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceBase, this);
            }
        }
Beispiel #12
0
        public static byte[] GetExportCookie(Transaction transaction, byte[] whereabouts)
        {
            ArgumentNullException.ThrowIfNull(transaction);
            ArgumentNullException.ThrowIfNull(whereabouts);

            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceOleTx, $"{nameof(TransactionInterop)}.{nameof(GetExportCookie)}");
            }

            byte[] cookie;

            // Copy the whereabouts so that it cannot be modified later.
            var whereaboutsCopy = new byte[whereabouts.Length];

            Buffer.BlockCopy(whereabouts, 0, whereaboutsCopy, 0, whereabouts.Length);

            // First, make sure we are working with an OletxTransaction.
            OletxTransaction oletxTx = ConvertToOletxTransaction(transaction);

            try
            {
                oletxTx.RealOletxTransaction.TransactionShim.Export(whereabouts, out cookie);
            }
            catch (COMException comException)
            {
                OletxTransactionManager.ProxyException(comException);

                // We are unsure of what the exception may mean.  It is possible that
                // we could get E_FAIL when trying to contact a transaction manager that is
                // being blocked by a fire wall.  On the other hand we may get a COMException
                // based on bad data.  The more common situation is that the data is fine
                // (since it is generated by Microsoft code) and the problem is with
                // communication.  So in this case we default for unknown exceptions to
                // assume that the problem is with communication.
                throw TransactionManagerCommunicationException.Create(null, comException);
            }

            if (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, $"{nameof(TransactionInterop)}.{nameof(GetExportCookie)}");
            }

            return(cookie);
        }
Beispiel #13
0
        // This routine writes the "header" for the recovery information, based on the
        // type of the calling object and its provided parameter collection.  This information
        // we be read back by the static Reenlist method to create the necessary transaction
        // manager object with the right parameters in order to do a ReenlistTransaction call.
        internal static byte[] GetRecoveryInformation(
            string?startupInfo,
            byte[] resourceManagerRecoveryInformation
            )
        {
            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceOleTx, $"{nameof(TransactionManager)}.{nameof(GetRecoveryInformation)}");
            }

            MemoryStream stream = new MemoryStream();

            byte[]? returnValue = null;

            try
            {
                // Manually write the recovery information
                BinaryWriter writer = new BinaryWriter(stream);

                writer.Write(CurrentRecoveryVersion);
                if (startupInfo != null)
                {
                    writer.Write(startupInfo);
                }
                else
                {
                    writer.Write("");
                }
                writer.Write(resourceManagerRecoveryInformation);
                writer.Flush();
                returnValue = stream.ToArray();
            }
            finally
            {
                stream.Close();
            }

            if (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, $"{nameof(TransactionManager)}.{nameof(GetRecoveryInformation)}");
            }

            return(returnValue);
        }
        public static byte[] GetWhereabouts()
        {
            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceOleTx, "TransactionInterop.GetWhereabouts");
            }

            byte[] returnValue = OletxTransactionManager.GetWhereabouts();

            if (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, "TransactionInterop.GetWhereabouts");
            }
            return(returnValue);
        }
Beispiel #15
0
        public static Transaction GetTransactionFromTransmitterPropagationToken(byte[] propagationToken)
        {
            ArgumentNullException.ThrowIfNull(propagationToken);

            if (propagationToken.Length < 24)
            {
                throw new ArgumentException(SR.InvalidArgument, nameof(propagationToken));
            }

            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceOleTx, "TransactionInterop.GetTransactionFromTransmitterPropagationToken");
            }

            // Extract the transaction guid from the propagation token to see if we already have a
            // transaction object for the transaction.
            // In a propagation token, the transaction guid is preceded by two version DWORDs.
            var txId = new Guid(propagationToken.AsSpan(8, 16));

            // First check to see if there is a promoted LTM transaction with the same ID.  If there is, just return that.
            Transaction?tx = TransactionManager.FindPromotedTransaction(txId);

            if (null != tx)
            {
                if (etwLog.IsEnabled())
                {
                    etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, "TransactionInterop.GetTransactionFromTransmitterPropagationToken");
                }

                return(tx);
            }

            OletxTransaction dTx = GetOletxTransactionFromTransmitterPropagationToken(propagationToken);

            // If a transaction is found then FindOrCreate will Dispose the distributed transaction created.
            Transaction returnValue = TransactionManager.FindOrCreatePromotedTransaction(txId, dTx);

            if (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, "TransactionInterop.GetTransactionFromTransmitterPropagationToken");
            }
            return(returnValue);
        }
Beispiel #16
0
        /// <summary>
        /// Create a promotable single phase enlistment that promotes to a distributed transaction manager other than MSDTC.
        /// </summary>
        /// <param name="promotableSinglePhaseNotification">The object that implements the IPromotableSinglePhaseNotification interface.</param>
        /// <param name="promoterType">
        /// The promoter type Guid that identifies the format of the byte[] that is returned by the ITransactionPromoter.Promote
        /// call that is implemented by the IPromotableSinglePhaseNotificationObject, and thus the promoter of the transaction.
        /// </param>
        /// <returns>
        /// True if the enlistment is successful.
        ///
        /// False if the transaction already has a durable enlistment or promotable single phase enlistment or
        /// if the transaction has already promoted. In this case, the caller will need to enlist in the transaction through other
        /// means.
        ///
        /// If the Transaction.PromoterType matches the promoter type supported by the caller, then the
        /// Transaction.PromotedToken can be retrieved and used to enlist directly with the identified distributed transaction manager.
        ///
        /// How the enlistment is created with the distributed transaction manager identified by the Transaction.PromoterType
        /// is defined by that distributed transaction manager.
        /// </returns>
        public bool EnlistPromotableSinglePhase(IPromotableSinglePhaseNotification promotableSinglePhaseNotification, Guid promoterType)
        {
            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceLtm, this);
            }

            if (Disposed)
            {
                throw new ObjectDisposedException(nameof(Transaction));
            }

            if (promotableSinglePhaseNotification == null)
            {
                throw new ArgumentNullException(nameof(promotableSinglePhaseNotification));
            }

            if (promoterType == Guid.Empty)
            {
                throw new ArgumentException(SR.PromoterTypeInvalid, nameof(promoterType));
            }

            if (_complete)
            {
                throw TransactionException.CreateTransactionCompletedException(DistributedTxId);
            }

            bool succeeded = false;

            lock (_internalTransaction)
            {
                Debug.Assert(_internalTransaction.State != null);
                succeeded = _internalTransaction.State.EnlistPromotableSinglePhase(_internalTransaction, promotableSinglePhaseNotification, this, promoterType);
            }

            if (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceLtm, this);
            }

            return(succeeded);
        }
Beispiel #17
0
        public void SetDistributedTransactionIdentifier(IPromotableSinglePhaseNotification promotableNotification,
                                                        Guid distributedTransactionIdentifier)
        {
            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceLtm, this);
            }

            if (Disposed)
            {
                throw new ObjectDisposedException(nameof(Transaction));
            }

            if (promotableNotification == null)
            {
                throw new ArgumentNullException(nameof(promotableNotification));
            }

            if (distributedTransactionIdentifier == Guid.Empty)
            {
                throw new ArgumentException(null, nameof(distributedTransactionIdentifier));
            }

            if (_complete)
            {
                throw TransactionException.CreateTransactionCompletedException(DistributedTxId);
            }

            lock (_internalTransaction)
            {
                Debug.Assert(_internalTransaction.State != null);
                _internalTransaction.State.SetDistributedTransactionId(_internalTransaction,
                                                                       promotableNotification,
                                                                       distributedTransactionIdentifier);

                if (etwLog.IsEnabled())
                {
                    etwLog.MethodExit(TraceSourceType.TraceSourceLtm, this);
                }
                return;
            }
        }
Beispiel #18
0
        // Forward the commit to the state machine to take the appropriate action.
        //
        public void Commit()
        {
            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceLtm, this);
                etwLog.TransactionCommit(this, "CommittableTransaction");
            }

            if (Disposed)
            {
                throw new ObjectDisposedException(nameof(CommittableTransaction));
            }

            lock (_internalTransaction)
            {
                if (_complete)
                {
                    throw TransactionException.CreateTransactionCompletedException(DistributedTxId);
                }

                Debug.Assert(_internalTransaction.State != null);
                _internalTransaction.State.BeginCommit(_internalTransaction, false, null, null);

                // now that commit has started wait for the monitor on the transaction to know
                // if the transaction is done.
                do
                {
                    if (_internalTransaction.State.IsCompleted(_internalTransaction))
                    {
                        break;
                    }
                } while (Monitor.Wait(_internalTransaction));

                _internalTransaction.State.EndCommit(_internalTransaction);
            }

            if (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceLtm, this);
            }
        }
        public static byte[] GetWhereabouts()
        {
            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceDistributed, "TransactionInterop.GetWhereabouts");
            }

            DistributedTransactionManager dTm = TransactionManager.DistributedTransactionManager;

            byte[] returnValue = dTm.GetWhereabouts();

            if (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceDistributed, "TransactionInterop.GetWhereabouts");
            }
            return(returnValue);
        }
        public static Transaction GetTransactionFromDtcTransaction(IDtcTransaction transactionNative)
        {
            ArgumentNullException.ThrowIfNull(transactionNative);

            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceOleTx, "TransactionInterop.GetTransactionFromDtcTransaction");
            }

            Transaction transaction = OletxTransactionManager.GetTransactionFromDtcTransaction(transactionNative);

            if (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, "TransactionInterop.GetTransactionFromDtcTransaction");
            }
            return(transaction);
        }
Beispiel #21
0
        // Forward request to the state machine to take the appropriate action.
        //
        public Enlistment EnlistVolatile(ISinglePhaseNotification singlePhaseNotification, EnlistmentOptions enlistmentOptions)
        {
            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceLtm, this);
            }

            if (Disposed)
            {
                throw new ObjectDisposedException(nameof(Transaction));
            }

            if (singlePhaseNotification == null)
            {
                throw new ArgumentNullException(nameof(singlePhaseNotification));
            }

            if (enlistmentOptions != EnlistmentOptions.None && enlistmentOptions != EnlistmentOptions.EnlistDuringPrepareRequired)
            {
                throw new ArgumentOutOfRangeException(nameof(enlistmentOptions));
            }

            if (_complete)
            {
                throw TransactionException.CreateTransactionCompletedException(DistributedTxId);
            }

            lock (_internalTransaction)
            {
                Debug.Assert(_internalTransaction.State != null);
                Enlistment enlistment = _internalTransaction.State.EnlistVolatile(_internalTransaction,
                                                                                  singlePhaseNotification, enlistmentOptions, this);

                if (etwLog.IsEnabled())
                {
                    etwLog.MethodExit(TraceSourceType.TraceSourceLtm, this);
                }
                return(enlistment);
            }
        }
Beispiel #22
0
        public void Done()
        {
            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceLtm, this);
                etwLog.EnlistmentDone(_internalEnlistment);
            }

            lock (_internalEnlistment.SyncRoot)
            {
                _internalEnlistment.State.EnlistmentDone(_internalEnlistment);
            }

            if (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceLtm, this);
            }
        }
        public void ForceRollback(Exception?e)
        {
            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceLtm, this);
                etwLog.EnlistmentForceRollback(_internalEnlistment);
            }

            lock (_internalEnlistment.SyncRoot)
            {
                _internalEnlistment.State.ForceRollback(_internalEnlistment, e);
            }

            if (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceLtm, this);
            }
        }
        public static byte[] GetTransmitterPropagationToken(Transaction transaction)
        {
            ArgumentNullException.ThrowIfNull(transaction);

            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceOleTx, "TransactionInterop.GetTransmitterPropagationToken");
            }

            ConvertToOletxTransaction(transaction);
            byte[] token = OletxTransaction.GetTransmitterPropagationToken();

            if (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, "TransactionInterop.GetTransmitterPropagationToken");
            }

            return(token);
        }
        public static IDtcTransaction GetDtcTransaction(Transaction transaction)
        {
            ArgumentNullException.ThrowIfNull(transaction);

            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceOleTx, "TransactionInterop.GetDtcTransaction");
            }

            ConvertToOletxTransaction(transaction);
            IDtcTransaction transactionNative = OletxTransaction.GetDtcTransaction();

            if (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, "TransactionInterop.GetDtcTransaction");
            }

            return(transactionNative);
        }
        public void Complete()
        {
            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceLtm, this);
            }

            lock (_internalTransaction)
            {
                if (Disposed)
                {
                    throw new ObjectDisposedException(nameof(DependentTransaction));
                }

                if (_complete)
                {
                    throw TransactionException.CreateTransactionCompletedException(DistributedTxId);
                }

                _complete = true;

                Debug.Assert(_internalTransaction.State != null);
                if (_blocking)
                {
                    _internalTransaction.State.CompleteBlockingClone(_internalTransaction);
                }
                else
                {
                    _internalTransaction.State.CompleteAbortingClone(_internalTransaction);
                }
            }

            if (etwLog.IsEnabled())
            {
                etwLog.TransactionDependentCloneComplete(this, "DependentTransaction");
                etwLog.MethodExit(TraceSourceType.TraceSourceLtm, this);
            }
        }
    internal void BeginCommit(InternalTransaction internalTransaction)
    {
        TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

        if (etwLog.IsEnabled())
        {
            etwLog.MethodEnter(TraceSourceType.TraceSourceOleTx, this);
            etwLog.TransactionCommit(TraceSourceType.TraceSourceOleTx, TransactionTraceId, "CommittableTransaction");
        }

        Debug.Assert(0 == Disposed, "OletxTransction object is disposed");
        RealOletxTransaction.InternalTransaction = internalTransaction;

        _commitCalled = true;

        RealOletxTransaction.Commit();

        if (etwLog.IsEnabled())
        {
            etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, this, $"{nameof(OletxCommittableTransaction)}.{nameof(BeginCommit)}");
        }
    }
Beispiel #28
0
        public static void RecoveryComplete(Guid resourceManagerIdentifier)
        {
            if (resourceManagerIdentifier == Guid.Empty)
            {
                throw new ArgumentException(SR.BadResourceManagerId, nameof(resourceManagerIdentifier));
            }

            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceBase, "TransactionManager.RecoveryComplete");
                etwLog.TransactionManagerRecoveryComplete(resourceManagerIdentifier);
            }

            DistributedTransactionManager.ResourceManagerRecoveryComplete(resourceManagerIdentifier);

            if (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceBase, "TransactionManager.RecoveryComplete");
            }
        }
        public static Transaction GetTransactionFromDtcTransaction(IDtcTransaction transactionNative)
        {
            if (null == transactionNative)
            {
                throw new ArgumentNullException(nameof(transactionNative));
            }

            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceDistributed, "TransactionInterop.GetTransactionFromDtcTransaction");
            }

            Transaction transaction = DistributedTransactionManager.GetTransactionFromDtcTransaction(transactionNative);

            if (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceDistributed, "TransactionInterop.GetTransactionFromDtcTransaction");
            }
            return(transaction);
        }
Beispiel #30
0
        public static byte[] GetTransmitterPropagationToken(Transaction transaction)
        {
            ArgumentNullException.ThrowIfNull(transaction);

            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceOleTx, $"{nameof(TransactionInterop)}.{nameof(GetTransmitterPropagationToken)}");
            }

            // First, make sure we are working with an OletxTransaction.
            OletxTransaction oletxTx = ConvertToOletxTransaction(transaction);

            byte[] token = GetTransmitterPropagationToken(oletxTx);

            if (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, $"{nameof(TransactionInterop)}.{nameof(GetTransmitterPropagationToken)}");
            }

            return(token);
        }