public object GetRealObject(StreamingContext context)
        {
            if (DiagnosticTrace.Verbose)
            {
                MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "IObjectReference.GetRealObject");
            }
            if (this.propagationTokenForDeserialize == null)
            {
                if (DiagnosticTrace.Critical)
                {
                    InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("UnableToDeserializeTransaction"));
                }
                throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("UnableToDeserializeTransactionInternalError"), null);
            }
            if (null != this.savedLtmPromotedTransaction)
            {
                if (DiagnosticTrace.Verbose)
                {
                    MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "IObjectReference.GetRealObject");
                }
                return(this.savedLtmPromotedTransaction);
            }
            Transaction transactionFromTransmitterPropagationToken = TransactionInterop.GetTransactionFromTransmitterPropagationToken(this.propagationTokenForDeserialize);

            this.savedLtmPromotedTransaction = transactionFromTransmitterPropagationToken;
            if (DiagnosticTrace.Verbose)
            {
                TransactionDeserializedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), transactionFromTransmitterPropagationToken.internalTransaction.PromotedTransaction.TransactionTraceId);
            }
            if (DiagnosticTrace.Verbose)
            {
                MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "IObjectReference.GetRealObject");
            }
            return(transactionFromTransmitterPropagationToken);
        }
 internal void Commit()
 {
     try
     {
         this.transactionShim.Commit();
     }
     catch (COMException exception)
     {
         if ((System.Transactions.Oletx.NativeMethods.XACT_E_ABORTED == exception.ErrorCode) || (System.Transactions.Oletx.NativeMethods.XACT_E_INDOUBT == exception.ErrorCode))
         {
             Interlocked.CompareExchange <Exception>(ref this.innerException, exception, null);
             if (DiagnosticTrace.Verbose)
             {
                 ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
             }
         }
         else
         {
             if (System.Transactions.Oletx.NativeMethods.XACT_E_ALREADYINPROGRESS == exception.ErrorCode)
             {
                 throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("TransactionAlreadyOver"), exception);
             }
             OletxTransactionManager.ProxyException(exception);
             throw;
         }
     }
 }
        internal OletxDependentTransaction DependentClone(bool delayCommit)
        {
            OletxDependentTransaction transaction = null;

            if (DiagnosticTrace.Verbose)
            {
                MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxTransaction.DependentClone");
            }
            if (TransactionStatus.Aborted == this.Status)
            {
                throw TransactionAbortedException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), this.realOletxTransaction.innerException);
            }
            if (TransactionStatus.InDoubt == this.Status)
            {
                throw TransactionInDoubtException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), this.realOletxTransaction.innerException);
            }
            if (this.Status != TransactionStatus.Active)
            {
                throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("TransactionAlreadyOver"), null);
            }
            transaction = new OletxDependentTransaction(this.realOletxTransaction, delayCommit);
            if (DiagnosticTrace.Verbose)
            {
                MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxTransaction.DependentClone");
            }
            return(transaction);
        }
 internal void Rollback()
 {
     lock (this)
     {
         if ((TransactionStatus.Aborted != this.status) && (this.status != TransactionStatus.Active))
         {
             throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("TransactionAlreadyOver"), null);
         }
         if (TransactionStatus.Aborted == this.status)
         {
             return;
         }
         if (0 < this.undecidedEnlistmentCount)
         {
             this.doomed = true;
         }
         else if (this.tooLateForEnlistments)
         {
             throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("TransactionAlreadyOver"), null);
         }
         if (this.phase0EnlistVolatilementContainerList != null)
         {
             foreach (OletxPhase0VolatileEnlistmentContainer container in this.phase0EnlistVolatilementContainerList)
             {
                 container.RollbackFromTransaction();
             }
         }
         if (this.phase1EnlistVolatilementContainer != null)
         {
             this.phase1EnlistVolatilementContainer.RollbackFromTransaction();
         }
     }
     try
     {
         this.transactionShim.Abort();
     }
     catch (COMException exception)
     {
         if (System.Transactions.Oletx.NativeMethods.XACT_E_ALREADYINPROGRESS == exception.ErrorCode)
         {
             if (!this.doomed)
             {
                 throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("TransactionAlreadyOver"), exception);
             }
             if (DiagnosticTrace.Verbose)
             {
                 ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
             }
         }
         else
         {
             OletxTransactionManager.ProxyException(exception);
             throw;
         }
     }
 }
Example #5
0
 internal void AddEnlistment(OletxVolatileEnlistment enlistment)
 {
     lock (this)
     {
         if (-1 != base.phase)
         {
             throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("TooLate"), null);
         }
         base.enlistmentList.Add(enlistment);
     }
 }
        internal IPromotedEnlistment EnlistDurable(Guid resourceManagerIdentifier, ISinglePhaseNotificationInternal singlePhaseNotification, bool canDoSinglePhase, EnlistmentOptions enlistmentOptions)
        {
            if (DiagnosticTrace.Verbose)
            {
                MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxTransaction.EnlistDurable( ISinglePhaseNotificationInternal )");
            }
            if ((this.realOletxTransaction == null) || this.realOletxTransaction.TooLateForEnlistments)
            {
                throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("TooLate"), null);
            }
            OletxEnlistment enlistment = this.realOletxTransaction.OletxTransactionManagerInstance.FindOrRegisterResourceManager(resourceManagerIdentifier).EnlistDurable(this, canDoSinglePhase, singlePhaseNotification, enlistmentOptions);

            if (DiagnosticTrace.Verbose)
            {
                MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxTransaction.EnlistDurable( ISinglePhaseNotificationInternal )");
            }
            return(enlistment);
        }
        internal IPromotedEnlistment EnlistVolatile(ISinglePhaseNotificationInternal singlePhaseNotification, EnlistmentOptions enlistmentOptions)
        {
            if (DiagnosticTrace.Verbose)
            {
                MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxTransaction.EnlistVolatile( ISinglePhaseNotificationInternal )");
            }
            if ((this.realOletxTransaction == null) || this.realOletxTransaction.TooLateForEnlistments)
            {
                throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("TooLate"), null);
            }
            IPromotedEnlistment enlistment = this.realOletxTransaction.EnlistVolatile(singlePhaseNotification, enlistmentOptions, this);

            if (DiagnosticTrace.Verbose)
            {
                MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxTransaction.EnlistVolatile( ISinglePhaseNotificationInternal )");
            }
            return(enlistment);
        }
Example #8
0
        internal static void ProxyException(
            COMException comException
            )
        {
            if ((NativeMethods.XACT_E_CONNECTION_DOWN == comException.ErrorCode) ||
                (NativeMethods.XACT_E_TMNOTAVAILABLE == comException.ErrorCode)
                )
            {
                throw TransactionManagerCommunicationException.Create(
                          SR.GetString(SR.TraceSourceOletx),
                          SR.GetString(SR.TransactionManagerCommunicationException),
                          comException
                          );
            }
            if ((NativeMethods.XACT_E_NETWORK_TX_DISABLED == comException.ErrorCode))
            {
                throw TransactionManagerCommunicationException.Create(
                          SR.GetString(SR.TraceSourceOletx),
                          SR.GetString(SR.NetworkTransactionsDisabled),
                          comException
                          );
            }
            // Else if the error is a transaction oriented error, throw a TransactionException
            else if ((NativeMethods.XACT_E_FIRST <= comException.ErrorCode) &&
                     (NativeMethods.XACT_E_LAST >= comException.ErrorCode))
            {
                // Special casing XACT_E_NOTRANSACTION
                if (NativeMethods.XACT_E_NOTRANSACTION == comException.ErrorCode)
                {
                    throw TransactionException.Create(
                              SR.GetString(SR.TraceSourceOletx),
                              SR.GetString(SR.TransactionAlreadyOver),
                              comException
                              );
                }

                throw TransactionException.Create(
                          SR.GetString(SR.TraceSourceOletx),
                          comException.Message,
                          comException
                          );
            }
        }
Example #9
0
 internal static void ProxyException(COMException comException)
 {
     if ((System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN == comException.ErrorCode) || (System.Transactions.Oletx.NativeMethods.XACT_E_TMNOTAVAILABLE == comException.ErrorCode))
     {
         throw TransactionManagerCommunicationException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("TransactionManagerCommunicationException"), comException);
     }
     if (System.Transactions.Oletx.NativeMethods.XACT_E_NETWORK_TX_DISABLED == comException.ErrorCode)
     {
         throw TransactionManagerCommunicationException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("NetworkTransactionsDisabled"), comException);
     }
     if ((System.Transactions.Oletx.NativeMethods.XACT_E_FIRST <= comException.ErrorCode) && (System.Transactions.Oletx.NativeMethods.XACT_E_LAST >= comException.ErrorCode))
     {
         if (System.Transactions.Oletx.NativeMethods.XACT_E_NOTRANSACTION == comException.ErrorCode)
         {
             throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("TransactionAlreadyOver"), comException);
         }
         throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), comException.Message, comException);
     }
 }
Example #10
0
 internal OletxTransactionManager(string nodeName)
 {
     lock (ClassSyncObject)
     {
         if (proxyShimFactory == null)
         {
             if (System.Transactions.Oletx.NativeMethods.GetNotificationFactory(ShimWaitHandle.SafeWaitHandle, out proxyShimFactory) != 0)
             {
                 throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("UnableToGetNotificationShimFactory"), null);
             }
             ThreadPool.UnsafeRegisterWaitForSingleObject(ShimWaitHandle, new WaitOrTimerCallback(OletxTransactionManager.ShimNotificationCallback), null, -1, false);
         }
     }
     this.dtcTransactionManagerLock = new ReaderWriterLock();
     this.nodeNameField             = nodeName;
     if ((this.nodeNameField != null) && (this.nodeNameField.Length == 0))
     {
         this.nodeNameField = null;
     }
     if (DiagnosticTrace.Verbose)
     {
         DistributedTransactionManagerCreatedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.GetType(), this.nodeNameField);
     }
     this.configuredTransactionOptions.IsolationLevel = this.isolationLevelProperty = TransactionManager.DefaultIsolationLevel;
     this.configuredTransactionOptions.Timeout        = this.timeoutProperty = TransactionManager.DefaultTimeout;
     this.internalResourceManager = new OletxInternalResourceManager(this);
     this.dtcTransactionManagerLock.AcquireWriterLock(-1);
     try
     {
         this.dtcTransactionManager = new System.Transactions.Oletx.DtcTransactionManager(this.nodeNameField, this);
     }
     finally
     {
         this.dtcTransactionManagerLock.ReleaseWriterLock();
     }
     if (resourceManagerHashTable == null)
     {
         resourceManagerHashTable     = new Hashtable(2);
         resourceManagerHashTableLock = new ReaderWriterLock();
     }
 }
Example #11
0
    internal OletxEnlistment EnlistDurable(
        OletxTransaction oletxTransaction,
        bool canDoSinglePhase,
        IEnlistmentNotificationInternal enlistmentNotification,
        EnlistmentOptions enlistmentOptions)
    {
        ResourceManagerShim?localResourceManagerShim;

        Debug.Assert(oletxTransaction != null, "Argument is null");
        Debug.Assert(enlistmentNotification != null, "Argument is null");

        EnlistmentShim       enlistmentShim;
        Phase0EnlistmentShim phase0Shim;
        Guid txUow = Guid.Empty;
        bool undecidedEnlistmentsIncremented = false;

        // Create our enlistment object.
        OletxEnlistment enlistment = new(
            canDoSinglePhase,
            enlistmentNotification,
            oletxTransaction.RealTransaction.TxGuid,
            enlistmentOptions,
            this,
            oletxTransaction);

        bool enlistmentSucceeded = false;

        try
        {
            if ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != 0)
            {
                oletxTransaction.RealTransaction.IncrementUndecidedEnlistments();
                undecidedEnlistmentsIncremented = true;
            }

            // This entire sequence needs to be executed before we can go on.
            lock (enlistment)
            {
                try
                {
                    // Do the enlistment on the proxy.
                    localResourceManagerShim = ResourceManagerShim;
                    if (localResourceManagerShim == null)
                    {
                        // The TM must be down.  Throw the appropriate exception.
                        throw TransactionManagerCommunicationException.Create(SR.TraceSourceOletx, null);
                    }

                    if ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != 0)
                    {
                        oletxTransaction.RealTransaction.TransactionShim.Phase0Enlist(enlistment, out phase0Shim);
                        enlistment.Phase0EnlistmentShim = phase0Shim;
                    }

                    localResourceManagerShim.Enlist(oletxTransaction.RealTransaction.TransactionShim, enlistment, out enlistmentShim);

                    enlistment.EnlistmentShim = enlistmentShim;
                }
                catch (COMException comException)
                {
                    // There is no string mapping for XACT_E_TOOMANY_ENLISTMENTS, so we need to do it here.
                    if (comException.ErrorCode == OletxHelper.XACT_E_TOOMANY_ENLISTMENTS)
                    {
                        throw TransactionException.Create(
                                  SR.OletxTooManyEnlistments,
                                  comException,
                                  enlistment == null ? Guid.Empty : enlistment.DistributedTxId);
                    }

                    OletxTransactionManager.ProxyException(comException);

                    throw;
                }
            }

            enlistmentSucceeded = true;
        }
        finally
        {
            if (!enlistmentSucceeded &&
                (enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != 0 &&
                undecidedEnlistmentsIncremented)
            {
                oletxTransaction.RealTransaction.DecrementUndecidedEnlistments();
            }
        }

        return(enlistment);
    }
Example #12
0
    internal void ReenlistThread(object?state)
    {
        int                 localLoopCount;
        bool                done;
        OletxEnlistment?    localEnlistment;
        ResourceManagerShim?localResourceManagerShim;
        bool                success;
        Timer?              localTimer        = null;
        bool                disposeLocalTimer = false;

        OletxResourceManager resourceManager = (OletxResourceManager)state !;

        try
        {
            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;
            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceOleTx, this, $"{nameof(OletxResourceManager)}.{nameof(ReenlistThread)}");
            }

            lock (resourceManager)
            {
                localResourceManagerShim = resourceManager.ResourceManagerShim;
                localTimer = resourceManager.ReenlistThreadTimer;
                resourceManager.ReenlistThreadTimer = null;
                resourceManager.reenlistThread      = Thread.CurrentThread;
            }

            // We only want to do work if we have a resourceManagerShim.
            if (localResourceManagerShim != null)
            {
                lock (resourceManager.ReenlistList)
                {
                    // Get the current count on the list.
                    localLoopCount = resourceManager.ReenlistList.Count;
                }

                done = false;
                while (!done && localLoopCount > 0 && localResourceManagerShim != null)
                {
                    lock (resourceManager.ReenlistList)
                    {
                        localEnlistment = null;
                        localLoopCount--;
                        if (resourceManager.ReenlistList.Count == 0)
                        {
                            done = true;
                        }
                        else
                        {
                            localEnlistment = resourceManager.ReenlistList[0] as OletxEnlistment;
                            if (localEnlistment == null)
                            {
                                if (etwLog.IsEnabled())
                                {
                                    etwLog.InternalError();
                                }

                                throw TransactionException.Create(SR.InternalError, null);
                            }

                            resourceManager.ReenlistList.RemoveAt(0);
                            object syncRoot = localEnlistment;
                            lock (syncRoot)
                            {
                                if (OletxEnlistment.OletxEnlistmentState.Done == localEnlistment.State)
                                {
                                    // We may be racing with a RecoveryComplete here.  Just forget about this
                                    // enlistment.
                                    localEnlistment = null;
                                }

                                else if (OletxEnlistment.OletxEnlistmentState.Prepared != localEnlistment.State)
                                {
                                    // The app hasn't yet responded to Prepare, so we don't know
                                    // if it is indoubt or not yet.  So just re-add it to the end
                                    // of the list.
                                    resourceManager.ReenlistList.Add(localEnlistment);
                                    localEnlistment = null;
                                }
                            }
                        }
                    }

                    if (localEnlistment != null)
                    {
                        OletxTransactionOutcome localOutcome = OletxTransactionOutcome.NotKnownYet;
                        try
                        {
                            Debug.Assert(localResourceManagerShim != null, "ReenlistThread - localResourceManagerShim is null");

                            // Make sure we have a prepare info.
                            if (localEnlistment.ProxyPrepareInfoByteArray == null)
                            {
                                Debug.Assert(false, string.Format(null, "this.prepareInfoByteArray == null in RecoveryInformation()"));
                                if (etwLog.IsEnabled())
                                {
                                    etwLog.InternalError();
                                }

                                throw TransactionException.Create(SR.InternalError, null);
                            }

                            localResourceManagerShim.Reenlist(localEnlistment.ProxyPrepareInfoByteArray, out localOutcome);

                            if (localOutcome == OletxTransactionOutcome.NotKnownYet)
                            {
                                object syncRoot = localEnlistment;
                                lock (syncRoot)
                                {
                                    if (OletxEnlistment.OletxEnlistmentState.Done == localEnlistment.State)
                                    {
                                        // We may be racing with a RecoveryComplete here.  Just forget about this
                                        // enlistment.
                                        localEnlistment = null;
                                    }
                                    else
                                    {
                                        // Put the enlistment back on the end of the list for retry later.
                                        lock (resourceManager.ReenlistList)
                                        {
                                            resourceManager.ReenlistList.Add(localEnlistment);
                                            localEnlistment = null;
                                        }
                                    }
                                }
                            }
                        }
                        catch (COMException ex) when(ex.ErrorCode == OletxHelper.XACT_E_CONNECTION_DOWN)
                        {
                            if (etwLog.IsEnabled())
                            {
                                etwLog.ExceptionConsumed(TraceSourceType.TraceSourceOleTx, ex);
                            }

                            // Release the resource manager so we can create a new one.
                            resourceManager.ResourceManagerShim = null;

                            // Now create a new resource manager with the proxy.
                            localResourceManagerShim = resourceManager.ResourceManagerShim;
                        }

                        // If we get here and we still have localEnlistment, then we got the outcome.
                        if (localEnlistment != null)
                        {
                            object syncRoot = localEnlistment;
                            lock (syncRoot)
                            {
                                if (OletxEnlistment.OletxEnlistmentState.Done == localEnlistment.State)
                                {
                                    // We may be racing with a RecoveryComplete here.  Just forget about this
                                    // enlistment.
                                    localEnlistment = null;
                                }
                                else
                                {
                                    // We are going to send the notification to the RM.  We need to put the
                                    // enlistment on the reenlistPendingList.  We lock the reenlistList because
                                    // we have decided that is the lock that protects both lists.  The entry will
                                    // be taken off the reenlistPendingList when the enlistment has
                                    // EnlistmentDone called on it.  The enlistment will call
                                    // RemoveFromReenlistPending.
                                    lock (resourceManager.ReenlistList)
                                    {
                                        resourceManager.ReenlistPendingList.Add(localEnlistment);
                                    }

                                    if (localOutcome == OletxTransactionOutcome.Committed)
                                    {
                                        localEnlistment.State = OletxEnlistment.OletxEnlistmentState.Committing;

                                        if (etwLog.IsEnabled())
                                        {
                                            etwLog.EnlistmentStatus(TraceSourceType.TraceSourceOleTx, localEnlistment.EnlistmentTraceId, NotificationCall.Commit);
                                        }

                                        localEnlistment.EnlistmentNotification !.Commit(localEnlistment);
                                    }
                                    else if (localOutcome == OletxTransactionOutcome.Aborted)
                                    {
                                        localEnlistment.State = OletxEnlistment.OletxEnlistmentState.Aborting;

                                        if (etwLog.IsEnabled())
                                        {
                                            etwLog.EnlistmentStatus(TraceSourceType.TraceSourceOleTx, localEnlistment.EnlistmentTraceId, NotificationCall.Rollback);
                                        }

                                        localEnlistment.EnlistmentNotification !.Rollback(localEnlistment);
                                    }
                                    else
                                    {
                                        if (etwLog.IsEnabled())
                                        {
                                            etwLog.InternalError();
                                        }

                                        throw TransactionException.Create(SR.InternalError, null);
                                    }
                                }
                            }
                        } // end of if null != localEnlistment
                    }     // end of if null != localEnlistment
                }
            }

            localResourceManagerShim = null;

            // Check to see if there is more work to do.
            lock (resourceManager.ReenlistList)
            {
                lock (resourceManager)
                {
                    // Get the current count on the list.
                    localLoopCount = resourceManager.ReenlistList.Count;
                    if (localLoopCount <= 0 && resourceManager.ReenlistPendingList.Count <= 0)
                    {
                        // No more entries on the list.  Try calling ReenlistComplete on the proxy, if
                        // appropriate.
                        // If the application has called RecoveryComplete,
                        // we are responsible for calling ReenlistComplete on the
                        // proxy.
                        success = resourceManager.CallProxyReenlistComplete();
                        if (success)
                        {
                            // Okay, the reenlist thread is done and we don't need to schedule another one.
                            disposeLocalTimer = true;
                        }
                        else
                        {
                            // We couldn't talk to the proxy to do ReenlistComplete, so schedule
                            // the thread again for 10 seconds from now.
                            resourceManager.ReenlistThreadTimer = localTimer;
                            if (!localTimer !.Change(10000, Timeout.Infinite))
                            {
                                throw TransactionException.CreateInvalidOperationException(
                                          TraceSourceType.TraceSourceLtm,
                                          SR.UnexpectedTimerFailure,
                                          null);
                            }
                        }
                    }
                    else
                    {
                        // There are still entries on the list, so they must not be
                        // resovled, yet.  Schedule the thread again in 10 seconds.
                        resourceManager.ReenlistThreadTimer = localTimer;
                        if (!localTimer !.Change(10000, Timeout.Infinite))
                        {
                            throw TransactionException.CreateInvalidOperationException(
                                      TraceSourceType.TraceSourceLtm,
                                      SR.UnexpectedTimerFailure,
                                      null);
                        }
                    }

                    resourceManager.reenlistThread = null;
                }

                if (etwLog.IsEnabled())
                {
                    etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, this, $"{nameof(OletxResourceManager)}.{nameof(ReenlistThread)}");
                }
            }
        }  // end of outer-most try
        finally
        {
            localResourceManagerShim = null;
            if (disposeLocalTimer && localTimer != null)
            {
                localTimer.Dispose();
            }
        }
    }  // end of ReenlistThread method;
Example #13
0
        internal OletxEnlistment Reenlist(int prepareInfoLength, byte[] prepareInfo, IEnlistmentNotificationInternal enlistmentNotification)
        {
            OletxRecoveryInformation information;
            OletxTransactionOutcome  notKnownYet         = OletxTransactionOutcome.NotKnownYet;
            OletxTransactionStatus   xactStatus          = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_NONE;
            MemoryStream             serializationStream = new MemoryStream(prepareInfo);
            IFormatter formatter = new BinaryFormatter();

            try
            {
                information = formatter.Deserialize(serializationStream) as OletxRecoveryInformation;
            }
            catch (SerializationException exception2)
            {
                throw new ArgumentException(System.Transactions.SR.GetString("InvalidArgument"), "prepareInfo", exception2);
            }
            if (information == null)
            {
                throw new ArgumentException(System.Transactions.SR.GetString("InvalidArgument"), "prepareInfo");
            }
            byte[] b = new byte[0x10];
            for (int i = 0; i < 0x10; i++)
            {
                b[i] = information.proxyRecoveryInformation[i + 0x10];
            }
            Guid guid = new Guid(b);

            if (guid != this.resourceManagerIdentifier)
            {
                throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("ResourceManagerIdDoesNotMatchRecoveryInformation"), null);
            }
            IResourceManagerShim resourceManagerShim = null;

            try
            {
                resourceManagerShim = this.ResourceManagerShim;
                if (resourceManagerShim == null)
                {
                    throw new COMException(System.Transactions.SR.GetString("DtcTransactionManagerUnavailable"), System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN);
                }
                resourceManagerShim.Reenlist(Convert.ToUInt32(information.proxyRecoveryInformation.Length, CultureInfo.InvariantCulture), information.proxyRecoveryInformation, out notKnownYet);
                if (OletxTransactionOutcome.Committed == notKnownYet)
                {
                    xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_COMMITTED;
                }
                else if (OletxTransactionOutcome.Aborted == notKnownYet)
                {
                    xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_ABORTED;
                }
                else
                {
                    xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_PREPARED;
                    this.StartReenlistThread();
                }
            }
            catch (COMException exception)
            {
                if (System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN != exception.ErrorCode)
                {
                    throw;
                }
                xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_PREPARED;
                this.ResourceManagerShim = null;
                this.StartReenlistThread();
                if (DiagnosticTrace.Verbose)
                {
                    ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
                }
            }
            finally
            {
                resourceManagerShim = null;
            }
            return(new OletxEnlistment(enlistmentNotification, xactStatus, information.proxyRecoveryInformation, this));
        }
Example #14
0
        internal void ReenlistThread(object state)
        {
            int                  count               = 0;
            bool                 flag                = false;
            OletxEnlistment      enlistment          = null;
            IResourceManagerShim resourceManagerShim = null;
            Timer                reenlistThreadTimer = null;
            bool                 flag2               = false;
            OletxResourceManager manager             = (OletxResourceManager)state;

            try
            {
                if (DiagnosticTrace.Information)
                {
                    MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxResourceManager.ReenlistThread");
                }
                lock (manager)
                {
                    resourceManagerShim         = manager.ResourceManagerShim;
                    reenlistThreadTimer         = manager.reenlistThreadTimer;
                    manager.reenlistThreadTimer = null;
                    manager.reenlistThread      = Thread.CurrentThread;
                }
                if (resourceManagerShim != null)
                {
                    lock (manager.reenlistList)
                    {
                        count = manager.reenlistList.Count;
                    }
                    flag = false;
                    while ((!flag && (count > 0)) && (resourceManagerShim != null))
                    {
                        lock (manager.reenlistList)
                        {
                            enlistment = null;
                            count--;
                            if (manager.reenlistList.Count == 0)
                            {
                                flag = true;
                            }
                            else
                            {
                                enlistment = manager.reenlistList[0] as OletxEnlistment;
                                if (enlistment == null)
                                {
                                    if (DiagnosticTrace.Critical)
                                    {
                                        InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
                                    }
                                    throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("InternalError"), null);
                                }
                                manager.reenlistList.RemoveAt(0);
                                object obj7 = enlistment;
                                lock (obj7)
                                {
                                    if (OletxEnlistment.OletxEnlistmentState.Done == enlistment.State)
                                    {
                                        enlistment = null;
                                    }
                                    else if (OletxEnlistment.OletxEnlistmentState.Prepared != enlistment.State)
                                    {
                                        manager.reenlistList.Add(enlistment);
                                        enlistment = null;
                                    }
                                }
                            }
                        }
                        if (enlistment != null)
                        {
                            OletxTransactionOutcome notKnownYet = OletxTransactionOutcome.NotKnownYet;
                            try
                            {
                                if (enlistment.ProxyPrepareInfoByteArray == null)
                                {
                                    if (DiagnosticTrace.Critical)
                                    {
                                        InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
                                    }
                                    throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("InternalError"), null);
                                }
                                resourceManagerShim.Reenlist((uint)enlistment.ProxyPrepareInfoByteArray.Length, enlistment.ProxyPrepareInfoByteArray, out notKnownYet);
                                if (notKnownYet == OletxTransactionOutcome.NotKnownYet)
                                {
                                    object obj5 = enlistment;
                                    lock (obj5)
                                    {
                                        if (OletxEnlistment.OletxEnlistmentState.Done == enlistment.State)
                                        {
                                            enlistment = null;
                                        }
                                        else
                                        {
                                            lock (manager.reenlistList)
                                            {
                                                manager.reenlistList.Add(enlistment);
                                                enlistment = null;
                                            }
                                        }
                                    }
                                }
                            }
                            catch (COMException exception)
                            {
                                if (System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN != exception.ErrorCode)
                                {
                                    throw;
                                }
                                if (DiagnosticTrace.Verbose)
                                {
                                    ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
                                }
                                if (System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN == exception.ErrorCode)
                                {
                                    manager.ResourceManagerShim = null;
                                    resourceManagerShim         = manager.ResourceManagerShim;
                                }
                            }
                            if (enlistment != null)
                            {
                                object obj3 = enlistment;
                                lock (obj3)
                                {
                                    if (OletxEnlistment.OletxEnlistmentState.Done != enlistment.State)
                                    {
                                        lock (manager.reenlistList)
                                        {
                                            manager.reenlistPendingList.Add(enlistment);
                                        }
                                        if (OletxTransactionOutcome.Committed != notKnownYet)
                                        {
                                            if (OletxTransactionOutcome.Aborted != notKnownYet)
                                            {
                                                if (DiagnosticTrace.Critical)
                                                {
                                                    InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
                                                }
                                                throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("InternalError"), null);
                                            }
                                            enlistment.State = OletxEnlistment.OletxEnlistmentState.Aborting;
                                            if (DiagnosticTrace.Verbose)
                                            {
                                                EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), enlistment.EnlistmentTraceId, NotificationCall.Rollback);
                                            }
                                            enlistment.EnlistmentNotification.Rollback(enlistment);
                                        }
                                        else
                                        {
                                            enlistment.State = OletxEnlistment.OletxEnlistmentState.Committing;
                                            if (DiagnosticTrace.Verbose)
                                            {
                                                EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), enlistment.EnlistmentTraceId, NotificationCall.Commit);
                                            }
                                            enlistment.EnlistmentNotification.Commit(enlistment);
                                        }
                                    }
                                    else
                                    {
                                        enlistment = null;
                                    }
                                    continue;
                                }
                            }
                        }
                    }
                }
                resourceManagerShim = null;
                lock (manager.reenlistList)
                {
                    lock (manager)
                    {
                        count = manager.reenlistList.Count;
                        if ((0 >= count) && (0 >= manager.reenlistPendingList.Count))
                        {
                            if (!manager.CallProxyReenlistComplete())
                            {
                                manager.reenlistThreadTimer = reenlistThreadTimer;
                                if (!reenlistThreadTimer.Change(0x2710, -1))
                                {
                                    throw TransactionException.CreateInvalidOperationException(System.Transactions.SR.GetString("TraceSourceLtm"), System.Transactions.SR.GetString("UnexpectedTimerFailure"), null);
                                }
                            }
                            else
                            {
                                flag2 = true;
                            }
                        }
                        else
                        {
                            manager.reenlistThreadTimer = reenlistThreadTimer;
                            if (!reenlistThreadTimer.Change(0x2710, -1))
                            {
                                throw TransactionException.CreateInvalidOperationException(System.Transactions.SR.GetString("TraceSourceLtm"), System.Transactions.SR.GetString("UnexpectedTimerFailure"), null);
                            }
                        }
                        manager.reenlistThread = null;
                    }
                    if (DiagnosticTrace.Information)
                    {
                        MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxResourceManager.ReenlistThread");
                    }
                }
            }
            finally
            {
                resourceManagerShim = null;
                if (flag2 && (reenlistThreadTimer != null))
                {
                    reenlistThreadTimer.Dispose();
                }
            }
        }
        internal OletxEnlistment(IEnlistmentNotificationInternal enlistmentNotification, OletxTransactionStatus xactStatus, byte[] prepareInfoByteArray, OletxResourceManager oletxResourceManager) : base(oletxResourceManager, null)
        {
            this.transactionGuid         = Guid.Empty;
            this.phase1Handle            = IntPtr.Zero;
            this.enlistmentShim          = null;
            this.phase0Shim              = null;
            this.canDoSinglePhase        = false;
            this.iEnlistmentNotification = enlistmentNotification;
            this.state = OletxEnlistmentState.Active;
            int length = prepareInfoByteArray.Length;

            this.proxyPrepareInfoByteArray = new byte[length];
            Array.Copy(prepareInfoByteArray, this.proxyPrepareInfoByteArray, length);
            byte[] destinationArray = new byte[0x10];
            Array.Copy(this.proxyPrepareInfoByteArray, destinationArray, 0x10);
            this.transactionGuid       = new Guid(destinationArray);
            base.transactionGuidString = this.transactionGuid.ToString();
            switch (xactStatus)
            {
            case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_PREPARED:
                this.state = OletxEnlistmentState.Prepared;
                lock (oletxResourceManager.reenlistList)
                {
                    oletxResourceManager.reenlistList.Add(this);
                    oletxResourceManager.StartReenlistThread();
                    goto Label_01CD;
                }
                break;

            case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_ABORTED:
                this.state = OletxEnlistmentState.Aborting;
                if (DiagnosticTrace.Verbose)
                {
                    EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.Rollback);
                }
                this.iEnlistmentNotification.Rollback(this);
                goto Label_01CD;

            case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_COMMITTED:
                this.state = OletxEnlistmentState.Committing;
                lock (oletxResourceManager.reenlistList)
                {
                    oletxResourceManager.reenlistPendingList.Add(this);
                }
                if (DiagnosticTrace.Verbose)
                {
                    EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.Commit);
                }
                this.iEnlistmentNotification.Commit(this);
                goto Label_01CD;
            }
            if (DiagnosticTrace.Critical)
            {
                InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("OletxEnlistmentUnexpectedTransactionStatus"));
            }
            throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("OletxEnlistmentUnexpectedTransactionStatus"), null);
Label_01CD:
            if (DiagnosticTrace.Information)
            {
                EnlistmentTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentType.Durable, EnlistmentOptions.None);
            }
            base.AddToEnlistmentTable();
        }
Example #16
0
    internal OletxEnlistment(
        IEnlistmentNotificationInternal enlistmentNotification,
        OletxTransactionStatus xactStatus,
        byte[] prepareInfoByteArray,
        OletxResourceManager oletxResourceManager)
        : base(oletxResourceManager, null)
    {
        // This will get set later by the creator of this object after it
        // has enlisted with the proxy.
        EnlistmentShim = null;
        _phase0Shim    = null;

        _canDoSinglePhase        = false;
        _iEnlistmentNotification = enlistmentNotification;
        State = OletxEnlistmentState.Active;

        // Do this before we do any tracing because it will affect the trace identifiers that we generate.
        Debug.Assert(prepareInfoByteArray != null,
                     "OletxEnlistment.ctor - null oletxTransaction without a prepareInfoByteArray");

        int prepareInfoLength = prepareInfoByteArray.Length;

        _proxyPrepareInfoByteArray = new byte[prepareInfoLength];
        Array.Copy(prepareInfoByteArray, _proxyPrepareInfoByteArray, prepareInfoLength);

        byte[] txGuidByteArray = new byte[16];
        Array.Copy(_proxyPrepareInfoByteArray, txGuidByteArray, 16);

        _transactionGuid      = new Guid(txGuidByteArray);
        TransactionGuidString = _transactionGuid.ToString();

        TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

        // If this is being created as part of a Reenlist and we already know the
        // outcome, then tell the application.
        switch (xactStatus)
        {
        case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_ABORTED:
        {
            State = OletxEnlistmentState.Aborting;
            if (etwLog.IsEnabled())
            {
                etwLog.EnlistmentStatus(TraceSourceType.TraceSourceOleTx, InternalTraceIdentifier, NotificationCall.Rollback);
            }

            _iEnlistmentNotification.Rollback(this);
            break;
        }

        case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_COMMITTED:
        {
            State = OletxEnlistmentState.Committing;
            // We are going to send the notification to the RM.  We need to put the
            // enlistment on the reenlistPendingList.  We lock the reenlistList because
            // we have decided that is the lock that protects both lists.  The entry will
            // be taken off the reenlistPendingList when the enlistment has
            // EnlistmentDone called on it.  The enlistment will call
            // RemoveFromReenlistPending.
            lock (oletxResourceManager.ReenlistList)
            {
                oletxResourceManager.ReenlistPendingList.Add(this);
            }

            if (etwLog.IsEnabled())
            {
                etwLog.EnlistmentStatus(TraceSourceType.TraceSourceOleTx, InternalTraceIdentifier, NotificationCall.Commit);
            }

            _iEnlistmentNotification.Commit(this);
            break;
        }

        case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_PREPARED:
        {
            State = OletxEnlistmentState.Prepared;
            lock (oletxResourceManager.ReenlistList)
            {
                oletxResourceManager.ReenlistList.Add(this);
                oletxResourceManager.StartReenlistThread();
            }
            break;
        }

        default:
        {
            if (etwLog.IsEnabled())
            {
                etwLog.InternalError(SR.OletxEnlistmentUnexpectedTransactionStatus);
            }

            throw TransactionException.Create(
                      SR.OletxEnlistmentUnexpectedTransactionStatus, null, DistributedTxId);
        }
        }

        if (etwLog.IsEnabled())
        {
            etwLog.EnlistmentCreated(TraceSourceType.TraceSourceOleTx, InternalTraceIdentifier, EnlistmentType.Durable, EnlistmentOptions.None);
        }

        // Always do this last in case anything prior to this fails.
        AddToEnlistmentTable();
    }
Example #17
0
    internal OletxEnlistment Reenlist(byte[] prepareInfo, IEnlistmentNotificationInternal enlistmentNotification)
    {
        OletxTransactionOutcome outcome    = OletxTransactionOutcome.NotKnownYet;
        OletxTransactionStatus  xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_NONE;

        if (prepareInfo == null)
        {
            throw new ArgumentException(SR.InvalidArgument, nameof(prepareInfo));
        }

        // Verify that the resource manager guid in the recovery info matches that of the calling resource manager.
        byte[] rmGuidArray = new byte[16];
        for (int i = 0; i < 16; i++)
        {
            rmGuidArray[i] = prepareInfo[i + 16];
        }
        Guid rmGuid = new(rmGuidArray);

        if (rmGuid != ResourceManagerIdentifier)
        {
            throw TransactionException.Create(TraceSourceType.TraceSourceOleTx, SR.ResourceManagerIdDoesNotMatchRecoveryInformation, null);
        }

        // Ask the proxy resource manager to reenlist.
        ResourceManagerShim?localResourceManagerShim = null;

        try
        {
            localResourceManagerShim = ResourceManagerShim;
            if (localResourceManagerShim == null)
            {
                // The TM must be down.  Throw the exception that will get caught below and will cause
                // the enlistment to start the ReenlistThread.  The TMDown thread will be trying to reestablish
                // connection with the TM and will start the reenlist thread when it does.
                throw new COMException(SR.DtcTransactionManagerUnavailable, OletxHelper.XACT_E_CONNECTION_DOWN);
            }

            // Only wait for 5 milliseconds.  If the TM doesn't have the outcome now, we will
            // put the enlistment on the reenlistList for later processing.
            localResourceManagerShim.Reenlist(prepareInfo, out outcome);

            if (OletxTransactionOutcome.Committed == outcome)
            {
                xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_COMMITTED;
            }
            else if (OletxTransactionOutcome.Aborted == outcome)
            {
                xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_ABORTED;
            }
            else  // we must not know the outcome yet.
            {
                xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_PREPARED;
                StartReenlistThread();
            }
        }
        catch (COMException ex) when(ex.ErrorCode == OletxHelper.XACT_E_CONNECTION_DOWN)
        {
            xactStatus          = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_PREPARED;
            ResourceManagerShim = null;
            StartReenlistThread();

            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.ExceptionConsumed(TraceSourceType.TraceSourceOleTx, ex);
            }
        }
        finally
        {
            localResourceManagerShim = null;
        }

        // Now create our enlistment to tell the client the outcome.
        return(new OletxEnlistment(enlistmentNotification, xactStatus, prepareInfo, this));
    }
Example #18
0
        internal OletxEnlistment EnlistDurable(OletxTransaction oletxTransaction, bool canDoSinglePhase, IEnlistmentNotificationInternal enlistmentNotification, EnlistmentOptions enlistmentOptions)
        {
            IResourceManagerShim  resourceManagerShim = null;
            IPhase0EnlistmentShim shim2          = null;
            IEnlistmentShim       enlistmentShim = null;
            IntPtr          zero   = IntPtr.Zero;
            bool            flag3  = false;
            bool            flag2  = false;
            OletxEnlistment target = new OletxEnlistment(canDoSinglePhase, enlistmentNotification, oletxTransaction.RealTransaction.TxGuid, enlistmentOptions, this, oletxTransaction);
            bool            flag   = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                if ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != EnlistmentOptions.None)
                {
                    RuntimeHelpers.PrepareConstrainedRegions();
                    try
                    {
                    }
                    finally
                    {
                        oletxTransaction.RealTransaction.IncrementUndecidedEnlistments();
                        flag2 = true;
                    }
                }
                lock (target)
                {
                    RuntimeHelpers.PrepareConstrainedRegions();
                    try
                    {
                        resourceManagerShim = this.ResourceManagerShim;
                        if (resourceManagerShim == null)
                        {
                            throw TransactionManagerCommunicationException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), null);
                        }
                        if ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != EnlistmentOptions.None)
                        {
                            zero = HandleTable.AllocHandle(target);
                            RuntimeHelpers.PrepareConstrainedRegions();
                            try
                            {
                            }
                            finally
                            {
                                oletxTransaction.RealTransaction.TransactionShim.Phase0Enlist(zero, out shim2);
                                flag3 = true;
                            }
                            target.Phase0EnlistmentShim = shim2;
                        }
                        target.phase1Handle = HandleTable.AllocHandle(target);
                        resourceManagerShim.Enlist(oletxTransaction.RealTransaction.TransactionShim, target.phase1Handle, out enlistmentShim);
                        target.EnlistmentShim = enlistmentShim;
                    }
                    catch (COMException exception)
                    {
                        if (System.Transactions.Oletx.NativeMethods.XACT_E_TOOMANY_ENLISTMENTS == exception.ErrorCode)
                        {
                            throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("OletxTooManyEnlistments"), exception);
                        }
                        OletxTransactionManager.ProxyException(exception);
                        throw;
                    }
                    finally
                    {
                        if (target.EnlistmentShim == null)
                        {
                            if ((zero != IntPtr.Zero) && !flag3)
                            {
                                HandleTable.FreeHandle(zero);
                            }
                            if (target.phase1Handle != IntPtr.Zero)
                            {
                                HandleTable.FreeHandle(target.phase1Handle);
                            }
                        }
                    }
                }
                flag = true;
            }
            finally
            {
                if ((!flag && ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != EnlistmentOptions.None)) && flag2)
                {
                    oletxTransaction.RealTransaction.DecrementUndecidedEnlistments();
                }
            }
            return(target);
        }
Example #19
0
        internal OletxTransactionManager(
            string nodeName
            )
        {
            lock ( ClassSyncObject )
            {
                // If we have not already initialized the shim factory and started the notification
                // thread, do so now.
                if (null == OletxTransactionManager.proxyShimFactory)
                {
                    Int32 error = NativeMethods.GetNotificationFactory(
                        OletxTransactionManager.ShimWaitHandle.SafeWaitHandle,
                        out OletxTransactionManager.proxyShimFactory
                        );

                    if (0 != error)
                    {
                        throw TransactionException.Create(SR.GetString(SR.TraceSourceOletx), SR.GetString(SR.UnableToGetNotificationShimFactory), null);
                    }

                    ThreadPool.UnsafeRegisterWaitForSingleObject(
                        OletxTransactionManager.ShimWaitHandle,
                        new WaitOrTimerCallback(OletxTransactionManager.ShimNotificationCallback),
                        null,
                        -1,
                        false
                        );
                }
            }

            this.dtcTransactionManagerLock = new ReaderWriterLock();

            this.nodeNameField = nodeName;

            // The DTC proxy doesn't like an empty string for node name on 64-bit platforms when
            // running as WOW64.  It treats any non-null node name as a "remote" node and turns off
            // the WOW64 bit, causing problems when reading the registry.  So if we got on empty
            // string for the node name, just treat it as null.
            if ((null != this.nodeNameField) && (0 == this.nodeNameField.Length))
            {
                this.nodeNameField = null;
            }

            if (DiagnosticTrace.Verbose)
            {
                DistributedTransactionManagerCreatedTraceRecord.Trace(SR.GetString(SR.TraceSourceOletx),
                                                                      this.GetType(),
                                                                      this.nodeNameField
                                                                      );
            }

            // Initialize the properties from config.
            configuredTransactionOptions.IsolationLevel = isolationLevelProperty = TransactionManager.DefaultIsolationLevel;
            configuredTransactionOptions.Timeout        = timeoutProperty = TransactionManager.DefaultTimeout;

            this.internalResourceManager = new OletxInternalResourceManager(this);

            dtcTransactionManagerLock.AcquireWriterLock(-1);
            try
            {
                this.dtcTransactionManager = new DtcTransactionManager(this.nodeNameField, this);
            }
            finally
            {
                dtcTransactionManagerLock.ReleaseWriterLock();
            }

            if (resourceManagerHashTable == null)
            {
                resourceManagerHashTable     = new Hashtable(2);
                resourceManagerHashTableLock = new System.Threading.ReaderWriterLock();
            }
        }