Пример #1
0
        internal OletxCommittableTransaction CreateTransaction(TransactionOptions properties)
        {
            OletxCommittableTransaction transaction          = null;
            ITransactionShim            transactionShim      = null;
            RealOletxTransaction        realOletxTransaction = null;
            Guid empty = Guid.Empty;
            OutcomeEnlistment target = null;

            new DistributedTransactionPermission(PermissionState.Unrestricted).Demand();
            TransactionManager.ValidateIsolationLevel(properties.IsolationLevel);
            if (IsolationLevel.Unspecified == properties.IsolationLevel)
            {
                properties.IsolationLevel = this.configuredTransactionOptions.IsolationLevel;
            }
            properties.Timeout = TransactionManager.ValidateTimeout(properties.Timeout);
            this.dtcTransactionManagerLock.AcquireReaderLock(-1);
            try
            {
                OletxTransactionIsolationLevel isolationLevel = ConvertIsolationLevel(properties.IsolationLevel);
                uint timeout = System.Transactions.Oletx.DtcTransactionManager.AdjustTimeout(properties.Timeout);
                target = new OutcomeEnlistment();
                IntPtr zero = IntPtr.Zero;
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                {
                    zero = HandleTable.AllocHandle(target);
                    this.dtcTransactionManager.ProxyShimFactory.BeginTransaction(timeout, isolationLevel, zero, out empty, out transactionShim);
                }
                catch (COMException exception)
                {
                    ProxyException(exception);
                    throw;
                }
                finally
                {
                    if ((transactionShim == null) && (zero != IntPtr.Zero))
                    {
                        HandleTable.FreeHandle(zero);
                    }
                }
                realOletxTransaction = new RealOletxTransaction(this, transactionShim, target, empty, isolationLevel, true);
                transaction          = new OletxCommittableTransaction(realOletxTransaction);
                if (DiagnosticTrace.Information)
                {
                    TransactionCreatedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), transaction.TransactionTraceId);
                }
            }
            finally
            {
                this.dtcTransactionManagerLock.ReleaseReaderLock();
            }
            return(transaction);
        }
        internal RealOletxTransaction(OletxTransactionManager transactionManager, ITransactionShim transactionShim, OutcomeEnlistment outcomeEnlistment, Guid identifier, OletxTransactionIsolationLevel oletxIsoLevel, bool isRoot)
        {
            bool flag = false;

            try
            {
                this.oletxTransactionManager = transactionManager;
                this.transactionShim         = transactionShim;
                this.outcomeEnlistment       = outcomeEnlistment;
                this.txGuid         = identifier;
                this.isolationLevel = OletxTransactionManager.ConvertIsolationLevelFromProxyValue(oletxIsoLevel);
                this.status         = TransactionStatus.Active;
                this.undisposedOletxTransactionCount       = 0;
                this.phase0EnlistVolatilementContainerList = null;
                this.phase1EnlistVolatilementContainer     = null;
                this.tooLateForEnlistments = false;
                this.internalTransaction   = null;
                this.creationTime          = DateTime.UtcNow;
                this.lastStateChangeTime   = this.creationTime;
                this.internalClone         = new OletxTransaction(this);
                if (this.outcomeEnlistment != null)
                {
                    this.outcomeEnlistment.SetRealTransaction(this);
                }
                else
                {
                    this.status = TransactionStatus.InDoubt;
                }
                if (DiagnosticTrace.HaveListeners)
                {
                    DiagnosticTrace.TraceTransfer(this.txGuid);
                }
                flag = true;
            }
            finally
            {
                if (!flag && (this.outcomeEnlistment != null))
                {
                    this.outcomeEnlistment.UnregisterOutcomeCallback();
                    this.outcomeEnlistment = null;
                }
            }
        }
 internal RealOletxTransaction(OletxTransactionManager transactionManager, ITransactionShim transactionShim, OutcomeEnlistment outcomeEnlistment, Guid identifier, OletxTransactionIsolationLevel oletxIsoLevel, bool isRoot)
 {
     bool flag = false;
     try
     {
         this.oletxTransactionManager = transactionManager;
         this.transactionShim = transactionShim;
         this.outcomeEnlistment = outcomeEnlistment;
         this.txGuid = identifier;
         this.isolationLevel = OletxTransactionManager.ConvertIsolationLevelFromProxyValue(oletxIsoLevel);
         this.status = TransactionStatus.Active;
         this.undisposedOletxTransactionCount = 0;
         this.phase0EnlistVolatilementContainerList = null;
         this.phase1EnlistVolatilementContainer = null;
         this.tooLateForEnlistments = false;
         this.internalTransaction = null;
         this.creationTime = DateTime.UtcNow;
         this.lastStateChangeTime = this.creationTime;
         this.internalClone = new OletxTransaction(this);
         if (this.outcomeEnlistment != null)
         {
             this.outcomeEnlistment.SetRealTransaction(this);
         }
         else
         {
             this.status = TransactionStatus.InDoubt;
         }
         if (DiagnosticTrace.HaveListeners)
         {
             DiagnosticTrace.TraceTransfer(this.txGuid);
         }
         flag = true;
     }
     finally
     {
         if (!flag && (this.outcomeEnlistment != null))
         {
             this.outcomeEnlistment.UnregisterOutcomeCallback();
             this.outcomeEnlistment = null;
         }
     }
 }
 internal OletxCommittableTransaction CreateTransaction(TransactionOptions properties)
 {
     OletxCommittableTransaction transaction = null;
     ITransactionShim transactionShim = null;
     RealOletxTransaction realOletxTransaction = null;
     Guid empty = Guid.Empty;
     OutcomeEnlistment target = null;
     new DistributedTransactionPermission(PermissionState.Unrestricted).Demand();
     TransactionManager.ValidateIsolationLevel(properties.IsolationLevel);
     if (IsolationLevel.Unspecified == properties.IsolationLevel)
     {
         properties.IsolationLevel = this.configuredTransactionOptions.IsolationLevel;
     }
     properties.Timeout = TransactionManager.ValidateTimeout(properties.Timeout);
     this.dtcTransactionManagerLock.AcquireReaderLock(-1);
     try
     {
         OletxTransactionIsolationLevel isolationLevel = ConvertIsolationLevel(properties.IsolationLevel);
         uint timeout = System.Transactions.Oletx.DtcTransactionManager.AdjustTimeout(properties.Timeout);
         target = new OutcomeEnlistment();
         IntPtr zero = IntPtr.Zero;
         RuntimeHelpers.PrepareConstrainedRegions();
         try
         {
             zero = HandleTable.AllocHandle(target);
             this.dtcTransactionManager.ProxyShimFactory.BeginTransaction(timeout, isolationLevel, zero, out empty, out transactionShim);
         }
         catch (COMException exception)
         {
             ProxyException(exception);
             throw;
         }
         finally
         {
             if ((transactionShim == null) && (zero != IntPtr.Zero))
             {
                 HandleTable.FreeHandle(zero);
             }
         }
         realOletxTransaction = new RealOletxTransaction(this, transactionShim, target, empty, isolationLevel, true);
         transaction = new OletxCommittableTransaction(realOletxTransaction);
         if (DiagnosticTrace.Information)
         {
             TransactionCreatedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), transaction.TransactionTraceId);
         }
     }
     finally
     {
         this.dtcTransactionManagerLock.ReleaseReaderLock();
     }
     return transaction;
 }
Пример #5
0
        internal static void ShimNotificationCallback(object state, bool timeout)
        {
            IntPtr zero = IntPtr.Zero;
            ShimNotificationType none            = ShimNotificationType.None;
            bool                 isSinglePhase   = false;
            bool                 abortingHint    = false;
            uint                 prepareInfoSize = 0;
            CoTaskMemHandle      prepareInfo     = null;
            bool                 releaseRequired = false;
            bool                 flag3           = false;
            IDtcProxyShimFactory factory         = null;

            if (DiagnosticTrace.Verbose)
            {
                MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxTransactionManager.ShimNotificationCallback");
            }
            Thread.BeginCriticalRegion();
            try
            {
Label_003D:
                factory = proxyShimFactory;
                try
                {
                    object obj2;
                    OletxResourceManager manager2;
                    byte[] buffer;
                    Thread.BeginThreadAffinity();
                    RuntimeHelpers.PrepareConstrainedRegions();
                    try
                    {
                        factory.GetNotification(out zero, out none, out isSinglePhase, out abortingHint, out releaseRequired, out prepareInfoSize, out prepareInfo);
                    }
                    finally
                    {
                        if (releaseRequired)
                        {
                            if (HandleTable.FindHandle(zero) is OletxInternalResourceManager)
                            {
                                processingTmDown = true;
                                Monitor.Enter(proxyShimFactory);
                            }
                            else
                            {
                                releaseRequired = false;
                            }
                            factory.ReleaseNotificationLock();
                        }
                        Thread.EndThreadAffinity();
                    }
                    if (processingTmDown)
                    {
                        lock (proxyShimFactory)
                        {
                        }
                    }
                    if (none != ShimNotificationType.None)
                    {
                        obj2 = HandleTable.FindHandle(zero);
                        switch (none)
                        {
                        case ShimNotificationType.Phase0RequestNotify:
                            try
                            {
                                OletxPhase0VolatileEnlistmentContainer container5 = obj2 as OletxPhase0VolatileEnlistmentContainer;
                                if (container5 != null)
                                {
                                    DiagnosticTrace.SetActivityId(container5.TransactionIdentifier);
                                    container5.Phase0Request(abortingHint);
                                }
                                else
                                {
                                    OletxEnlistment enlistment8 = obj2 as OletxEnlistment;
                                    if (enlistment8 != null)
                                    {
                                        DiagnosticTrace.SetActivityId(enlistment8.TransactionIdentifier);
                                        enlistment8.Phase0Request(abortingHint);
                                    }
                                    else
                                    {
                                        Environment.FailFast(System.Transactions.SR.GetString("InternalError"));
                                    }
                                }
                                goto Label_0444;
                            }
                            finally
                            {
                                HandleTable.FreeHandle(zero);
                            }
                            break;

                        case ShimNotificationType.VoteRequestNotify:
                            break;

                        case ShimNotificationType.PrepareRequestNotify:
                            goto Label_02B0;

                        case ShimNotificationType.CommitRequestNotify:
                            goto Label_031A;

                        case ShimNotificationType.AbortRequestNotify:
                            goto Label_0358;

                        case ShimNotificationType.CommittedNotify:
                            try
                            {
                                OutcomeEnlistment enlistment7 = obj2 as OutcomeEnlistment;
                                if (enlistment7 != null)
                                {
                                    DiagnosticTrace.SetActivityId(enlistment7.TransactionIdentifier);
                                    enlistment7.Committed();
                                }
                                else
                                {
                                    OletxPhase1VolatileEnlistmentContainer container3 = obj2 as OletxPhase1VolatileEnlistmentContainer;
                                    if (container3 != null)
                                    {
                                        DiagnosticTrace.SetActivityId(container3.TransactionIdentifier);
                                        container3.Committed();
                                    }
                                    else
                                    {
                                        Environment.FailFast(System.Transactions.SR.GetString("InternalError"));
                                    }
                                }
                                goto Label_0444;
                            }
                            finally
                            {
                                HandleTable.FreeHandle(zero);
                            }
                            goto Label_0203;

                        case ShimNotificationType.AbortedNotify:
                            goto Label_0203;

                        case ShimNotificationType.InDoubtNotify:
                            goto Label_0251;

                        case ShimNotificationType.EnlistmentTmDownNotify:
                            goto Label_0396;

                        case ShimNotificationType.ResourceManagerTmDownNotify:
                            goto Label_03CD;

                        default:
                            goto Label_0410;
                        }
                        OletxPhase1VolatileEnlistmentContainer container4 = obj2 as OletxPhase1VolatileEnlistmentContainer;
                        if (container4 != null)
                        {
                            DiagnosticTrace.SetActivityId(container4.TransactionIdentifier);
                            container4.VoteRequest();
                        }
                        else
                        {
                            Environment.FailFast(System.Transactions.SR.GetString("InternalError"));
                        }
                    }
                    goto Label_0444;
                    Label_0203 :;
                    try
                    {
                        OutcomeEnlistment enlistment6 = obj2 as OutcomeEnlistment;
                        if (enlistment6 != null)
                        {
                            DiagnosticTrace.SetActivityId(enlistment6.TransactionIdentifier);
                            enlistment6.Aborted();
                        }
                        else
                        {
                            OletxPhase1VolatileEnlistmentContainer container2 = obj2 as OletxPhase1VolatileEnlistmentContainer;
                            if (container2 != null)
                            {
                                DiagnosticTrace.SetActivityId(container2.TransactionIdentifier);
                                container2.Aborted();
                            }
                        }
                        goto Label_0444;
                    }
                    finally
                    {
                        HandleTable.FreeHandle(zero);
                    }
                    Label_0251 :;
                    try
                    {
                        OutcomeEnlistment enlistment5 = obj2 as OutcomeEnlistment;
                        if (enlistment5 != null)
                        {
                            DiagnosticTrace.SetActivityId(enlistment5.TransactionIdentifier);
                            enlistment5.InDoubt();
                        }
                        else
                        {
                            OletxPhase1VolatileEnlistmentContainer container = obj2 as OletxPhase1VolatileEnlistmentContainer;
                            if (container != null)
                            {
                                DiagnosticTrace.SetActivityId(container.TransactionIdentifier);
                                container.InDoubt();
                            }
                            else
                            {
                                Environment.FailFast(System.Transactions.SR.GetString("InternalError"));
                            }
                        }
                        goto Label_0444;
                    }
                    finally
                    {
                        HandleTable.FreeHandle(zero);
                    }
Label_02B0:
                    buffer = new byte[prepareInfoSize];
                    Marshal.Copy(prepareInfo.DangerousGetHandle(), buffer, 0, Convert.ToInt32(prepareInfoSize));
                    bool flag2 = true;
                    try
                    {
                        OletxEnlistment enlistment4 = obj2 as OletxEnlistment;
                        if (enlistment4 != null)
                        {
                            DiagnosticTrace.SetActivityId(enlistment4.TransactionIdentifier);
                            flag2 = enlistment4.PrepareRequest(isSinglePhase, buffer);
                        }
                        else
                        {
                            Environment.FailFast(System.Transactions.SR.GetString("InternalError"));
                        }
                        goto Label_0444;
                    }
                    finally
                    {
                        if (flag2)
                        {
                            HandleTable.FreeHandle(zero);
                        }
                    }
                    Label_031A :;
                    try
                    {
                        OletxEnlistment enlistment3 = obj2 as OletxEnlistment;
                        if (enlistment3 != null)
                        {
                            DiagnosticTrace.SetActivityId(enlistment3.TransactionIdentifier);
                            enlistment3.CommitRequest();
                        }
                        else
                        {
                            Environment.FailFast(System.Transactions.SR.GetString("InternalError"));
                        }
                        goto Label_0444;
                    }
                    finally
                    {
                        HandleTable.FreeHandle(zero);
                    }
                    Label_0358 :;
                    try
                    {
                        OletxEnlistment enlistment2 = obj2 as OletxEnlistment;
                        if (enlistment2 != null)
                        {
                            DiagnosticTrace.SetActivityId(enlistment2.TransactionIdentifier);
                            enlistment2.AbortRequest();
                        }
                        else
                        {
                            Environment.FailFast(System.Transactions.SR.GetString("InternalError"));
                        }
                        goto Label_0444;
                    }
                    finally
                    {
                        HandleTable.FreeHandle(zero);
                    }
                    Label_0396 :;
                    try
                    {
                        OletxEnlistment enlistment = obj2 as OletxEnlistment;
                        if (enlistment != null)
                        {
                            DiagnosticTrace.SetActivityId(enlistment.TransactionIdentifier);
                            enlistment.TMDown();
                        }
                        else
                        {
                            Environment.FailFast(System.Transactions.SR.GetString("InternalError"));
                        }
                        goto Label_0444;
                    }
                    finally
                    {
                        HandleTable.FreeHandle(zero);
                    }
Label_03CD:
                    manager2 = obj2 as OletxResourceManager;
                    try
                    {
                        if (manager2 != null)
                        {
                            manager2.TMDown();
                        }
                        else
                        {
                            OletxInternalResourceManager manager = obj2 as OletxInternalResourceManager;
                            if (manager != null)
                            {
                                manager.TMDown();
                            }
                            else
                            {
                                Environment.FailFast(System.Transactions.SR.GetString("InternalError"));
                            }
                        }
                        goto Label_0444;
                    }
                    finally
                    {
                        HandleTable.FreeHandle(zero);
                    }
Label_0410:
                    Environment.FailFast(System.Transactions.SR.GetString("InternalError"));
                }
                finally
                {
                    if (prepareInfo != null)
                    {
                        prepareInfo.Close();
                    }
                    if (releaseRequired)
                    {
                        releaseRequired  = false;
                        processingTmDown = false;
                        Monitor.Exit(proxyShimFactory);
                    }
                }
Label_0444:
                if (none != ShimNotificationType.None)
                {
                    goto Label_003D;
                }
                flag3 = true;
            }
            finally
            {
                if (releaseRequired)
                {
                    releaseRequired  = false;
                    processingTmDown = false;
                    Monitor.Exit(proxyShimFactory);
                }
                if (!flag3 && (zero != IntPtr.Zero))
                {
                    HandleTable.FreeHandle(zero);
                }
                Thread.EndCriticalRegion();
            }
            if (DiagnosticTrace.Verbose)
            {
                MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxTransactionManager.ShimNotificationCallback");
            }
        }
 public static Transaction GetTransactionFromExportCookie(byte[] cookie)
 {
     if (!TransactionManager._platformValidated)
     {
         TransactionManager.ValidatePlatform();
     }
     if (cookie == null)
     {
         throw new ArgumentNullException("cookie");
     }
     if (cookie.Length < 0x20)
     {
         throw new ArgumentException(System.Transactions.SR.GetString("InvalidArgument"), "cookie");
     }
     if (DiagnosticTrace.Verbose)
     {
         MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "TransactionInterop.GetTransactionFromExportCookie");
     }
     byte[] destinationArray = new byte[cookie.Length];
     Array.Copy(cookie, destinationArray, cookie.Length);
     cookie = destinationArray;
     Transaction transaction = null;
     ITransactionShim transactionShim = null;
     Guid empty = Guid.Empty;
     OletxTransactionIsolationLevel isolationLevel = OletxTransactionIsolationLevel.ISOLATIONLEVEL_SERIALIZABLE;
     OutcomeEnlistment target = null;
     OletxTransaction oletx = null;
     byte[] b = new byte[0x10];
     for (int i = 0; i < b.Length; i++)
     {
         b[i] = cookie[i + 0x10];
     }
     Guid transactionIdentifier = new Guid(b);
     transaction = TransactionManager.FindPromotedTransaction(transactionIdentifier);
     if (null != transaction)
     {
         if (DiagnosticTrace.Verbose)
         {
             MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "TransactionInterop.GetTransactionFromExportCookie");
         }
         return transaction;
     }
     RealOletxTransaction realOletxTransaction = null;
     OletxTransactionManager distributedTransactionManager = TransactionManager.DistributedTransactionManager;
     distributedTransactionManager.dtcTransactionManagerLock.AcquireReaderLock(-1);
     try
     {
         target = new OutcomeEnlistment();
         IntPtr zero = IntPtr.Zero;
         RuntimeHelpers.PrepareConstrainedRegions();
         try
         {
             zero = HandleTable.AllocHandle(target);
             distributedTransactionManager.DtcTransactionManager.ProxyShimFactory.Import(Convert.ToUInt32(cookie.Length), cookie, zero, out empty, out isolationLevel, out transactionShim);
         }
         finally
         {
             if ((transactionShim == null) && (zero != IntPtr.Zero))
             {
                 HandleTable.FreeHandle(zero);
             }
         }
     }
     catch (COMException exception)
     {
         OletxTransactionManager.ProxyException(exception);
         throw TransactionManagerCommunicationException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
     }
     finally
     {
         distributedTransactionManager.dtcTransactionManagerLock.ReleaseReaderLock();
     }
     realOletxTransaction = new RealOletxTransaction(distributedTransactionManager, transactionShim, target, empty, isolationLevel, false);
     oletx = new OletxTransaction(realOletxTransaction);
     transaction = TransactionManager.FindOrCreatePromotedTransaction(transactionIdentifier, oletx);
     if (DiagnosticTrace.Verbose)
     {
         MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "TransactionInterop.GetTransactionFromExportCookie");
     }
     return transaction;
 }
 public static Transaction GetTransactionFromDtcTransaction(IDtcTransaction transactionNative)
 {
     OletxXactTransInfo info;
     if (!TransactionManager._platformValidated)
     {
         TransactionManager.ValidatePlatform();
     }
     bool flag = false;
     ITransactionShim transactionShim = null;
     Guid empty = Guid.Empty;
     OletxTransactionIsolationLevel isolationLevel = OletxTransactionIsolationLevel.ISOLATIONLEVEL_SERIALIZABLE;
     OutcomeEnlistment target = null;
     RealOletxTransaction realOletxTransaction = null;
     OletxTransaction oletx = null;
     if (transactionNative == null)
     {
         throw new ArgumentNullException("transactionNative");
     }
     Transaction transaction = null;
     if (DiagnosticTrace.Verbose)
     {
         MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "TransactionInterop.GetTransactionFromDtc");
     }
     ITransactionNativeInternal internal2 = transactionNative as ITransactionNativeInternal;
     if (internal2 == null)
     {
         throw new ArgumentException(System.Transactions.SR.GetString("InvalidArgument"), "transactionNative");
     }
     try
     {
         internal2.GetTransactionInfo(out info);
     }
     catch (COMException exception2)
     {
         if (System.Transactions.Oletx.NativeMethods.XACT_E_NOTRANSACTION != exception2.ErrorCode)
         {
             throw;
         }
         flag = true;
         info.uow = Guid.Empty;
     }
     OletxTransactionManager distributedTransactionManager = TransactionManager.DistributedTransactionManager;
     if (!flag)
     {
         transaction = TransactionManager.FindPromotedTransaction(info.uow);
         if (null != transaction)
         {
             if (DiagnosticTrace.Verbose)
             {
                 MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "TransactionInterop.GetTransactionFromDtcTransaction");
             }
             return transaction;
         }
         distributedTransactionManager.dtcTransactionManagerLock.AcquireReaderLock(-1);
         try
         {
             target = new OutcomeEnlistment();
             IntPtr zero = IntPtr.Zero;
             RuntimeHelpers.PrepareConstrainedRegions();
             try
             {
                 zero = HandleTable.AllocHandle(target);
                 distributedTransactionManager.DtcTransactionManager.ProxyShimFactory.CreateTransactionShim(transactionNative, zero, out empty, out isolationLevel, out transactionShim);
             }
             finally
             {
                 if ((transactionShim == null) && (zero != IntPtr.Zero))
                 {
                     HandleTable.FreeHandle(zero);
                 }
             }
         }
         catch (COMException exception)
         {
             OletxTransactionManager.ProxyException(exception);
             throw;
         }
         finally
         {
             distributedTransactionManager.dtcTransactionManagerLock.ReleaseReaderLock();
         }
         realOletxTransaction = new RealOletxTransaction(distributedTransactionManager, transactionShim, target, empty, isolationLevel, false);
         oletx = new OletxTransaction(realOletxTransaction);
         transaction = TransactionManager.FindOrCreatePromotedTransaction(info.uow, oletx);
     }
     else
     {
         realOletxTransaction = new RealOletxTransaction(distributedTransactionManager, null, null, empty, OletxTransactionIsolationLevel.ISOLATIONLEVEL_SERIALIZABLE, false);
         oletx = new OletxTransaction(realOletxTransaction);
         transaction = new Transaction(oletx);
         TransactionManager.FireDistributedTransactionStarted(transaction);
         oletx.savedLtmPromotedTransaction = transaction;
         InternalTransaction.DistributedTransactionOutcome(transaction.internalTransaction, TransactionStatus.InDoubt);
     }
     if (DiagnosticTrace.Verbose)
     {
         MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "TransactionInterop.GetTransactionFromDtc");
     }
     return transaction;
 }
 internal static OletxTransaction GetOletxTransactionFromTransmitterPropigationToken(byte[] propagationToken)
 {
     OutcomeEnlistment enlistment;
     ITransactionShim transactionShim = null;
     OletxTransactionIsolationLevel level;
     Guid guid;
     if (propagationToken == null)
     {
         throw new ArgumentNullException("propagationToken");
     }
     if (propagationToken.Length < 0x18)
     {
         throw new ArgumentException(System.Transactions.SR.GetString("InvalidArgument"), "propagationToken");
     }
     byte[] destinationArray = new byte[propagationToken.Length];
     Array.Copy(propagationToken, destinationArray, propagationToken.Length);
     propagationToken = destinationArray;
     OletxTransactionManager distributedTransactionManager = TransactionManager.DistributedTransactionManager;
     distributedTransactionManager.dtcTransactionManagerLock.AcquireReaderLock(-1);
     try
     {
         enlistment = new OutcomeEnlistment();
         IntPtr zero = IntPtr.Zero;
         RuntimeHelpers.PrepareConstrainedRegions();
         try
         {
             zero = HandleTable.AllocHandle(enlistment);
             distributedTransactionManager.DtcTransactionManager.ProxyShimFactory.ReceiveTransaction(Convert.ToUInt32(propagationToken.Length), propagationToken, zero, out guid, out level, out transactionShim);
         }
         finally
         {
             if ((transactionShim == null) && (zero != IntPtr.Zero))
             {
                 HandleTable.FreeHandle(zero);
             }
         }
     }
     catch (COMException exception)
     {
         OletxTransactionManager.ProxyException(exception);
         throw TransactionManagerCommunicationException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
     }
     finally
     {
         distributedTransactionManager.dtcTransactionManagerLock.ReleaseReaderLock();
     }
     return new OletxTransaction(new RealOletxTransaction(distributedTransactionManager, transactionShim, enlistment, guid, level, false));
 }
Пример #9
0
        // Common constructor used by all types of constructors
        // Create a clean and fresh transaction.
        internal RealOletxTransaction(OletxTransactionManager transactionManager, 
            ITransactionShim transactionShim,
            OutcomeEnlistment outcomeEnlistment,
            Guid identifier,
            OletxTransactionIsolationLevel oletxIsoLevel,
            bool isRoot )
        {
            bool successful = false;

            try
            {
                // initialize the member fields
                this.oletxTransactionManager = transactionManager;
                this.transactionShim = transactionShim;
                this.outcomeEnlistment = outcomeEnlistment;
                this.txGuid = identifier;
                this.isolationLevel = OletxTransactionManager.ConvertIsolationLevelFromProxyValue( oletxIsoLevel );
                this.status = TransactionStatus.Active;
                this.undisposedOletxTransactionCount = 0;
                this.phase0EnlistVolatilementContainerList = null;
                this.phase1EnlistVolatilementContainer = null;
                this.tooLateForEnlistments = false;
                this.internalTransaction = null;

                this.creationTime = DateTime.UtcNow;
                this.lastStateChangeTime = this.creationTime;

                // Connect this object with the OutcomeEnlistment.
                this.internalClone = new OletxTransaction( this );

                // We have have been created without an outcome enlistment if it was too late to create
                // a clone from the ITransactionNative that we were created from.
                if ( null != this.outcomeEnlistment )
                {
                    this.outcomeEnlistment.SetRealTransaction( this );
                }
                else
                {
                    this.status = TransactionStatus.InDoubt;
                }

                if ( DiagnosticTrace.HaveListeners )
                {
                    DiagnosticTrace.TraceTransfer(this.txGuid);
                }

                successful = true;
            }
            finally
            {
                if (!successful)
                {
                    if (this.outcomeEnlistment != null)
                    {
                        this.outcomeEnlistment.UnregisterOutcomeCallback();
                        this.outcomeEnlistment = null;
                    }
                }
            }
               
        }
        public static Transaction GetTransactionFromDtcTransaction(
            IDtcTransaction transactionNative
            )
        {
            if ( !TransactionManager._platformValidated ) TransactionManager.ValidatePlatform();

            bool tooLate = false;
            ITransactionShim transactionShim = null;
            Guid txIdentifier = Guid.Empty;
            OletxTransactionIsolationLevel oletxIsoLevel = OletxTransactionIsolationLevel.ISOLATIONLEVEL_SERIALIZABLE;
            OutcomeEnlistment outcomeEnlistment = null;
            RealOletxTransaction realTx = null;
            OletxTransaction oleTx = null;

            if ( null == transactionNative )
            {
                throw new ArgumentNullException( "transactionNative" );
            }

            Transaction transaction = null;

            if ( DiagnosticTrace.Verbose )
            {
                MethodEnteredTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    "TransactionInterop.GetTransactionFromDtc"
                    );
            }

            // Let's get the guid of the transaction from the proxy to see if we already
            // have an object.
            ITransactionNativeInternal myTransactionNative = transactionNative as ITransactionNativeInternal;
            if ( null == myTransactionNative )
            {
                throw new ArgumentException( SR.GetString( SR.InvalidArgument ), "transactionNative" );
            }

            OletxXactTransInfo xactInfo;
            try
            {
                myTransactionNative.GetTransactionInfo( out xactInfo );
            }
            catch ( COMException ex )
            {
                if ( Oletx.NativeMethods.XACT_E_NOTRANSACTION != ex.ErrorCode )
                {
                    throw;
                }

                // If we get here, the transaction has appraently already been committed or aborted.  Allow creation of the
                // OletxTransaction, but it will be marked with a status of InDoubt and attempts to get its Identifier
                // property will result in a TransactionException.
                tooLate = true;
                xactInfo.uow = Guid.Empty;

            }

            OletxTransactionManager oletxTm = TransactionManager.DistributedTransactionManager;
            if ( ! tooLate )
            {
                // First check to see if there is a promoted LTM transaction with the same ID.  If there
                // is, just return that.
                transaction = TransactionManager.FindPromotedTransaction( xactInfo.uow );
                if ( null != transaction )
                {
                    if ( DiagnosticTrace.Verbose )
                    {
                        MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            "TransactionInterop.GetTransactionFromDtcTransaction"
                            );
                    }
                    return transaction;
                }

                // We need to create a new RealOletxTransaction...
                oletxTm.dtcTransactionManagerLock.AcquireReaderLock( -1 );
                try
                {
                    outcomeEnlistment = new OutcomeEnlistment();
                    IntPtr outcomeEnlistmentHandle = IntPtr.Zero;
                    RuntimeHelpers.PrepareConstrainedRegions();
                    try
                    {
                        outcomeEnlistmentHandle = HandleTable.AllocHandle( outcomeEnlistment );
                        oletxTm.DtcTransactionManager.ProxyShimFactory.CreateTransactionShim(
                            transactionNative,
                            outcomeEnlistmentHandle,
                            out txIdentifier,
                            out oletxIsoLevel,
                            out transactionShim );
                    }
                    finally
                    {
                        if ( transactionShim == null && outcomeEnlistmentHandle != IntPtr.Zero )
                        {
                            HandleTable.FreeHandle( outcomeEnlistmentHandle );
                        }
                    }
                }
                catch ( COMException comException )
                {
                    OletxTransactionManager.ProxyException( comException );
                    throw;
                }
                finally
                {
                    oletxTm.dtcTransactionManagerLock.ReleaseReaderLock();
                }

                // We need to create a new RealOletxTransaction.
                realTx = new RealOletxTransaction(
                    oletxTm,
                    transactionShim,
                    outcomeEnlistment,
                    txIdentifier,
                    oletxIsoLevel,
                    false );

                oleTx = new OletxTransaction( realTx );

                // If a transaction is found then FindOrCreate will Dispose the oletx
                // created.
                transaction = TransactionManager.FindOrCreatePromotedTransaction( xactInfo.uow, oleTx );
            }
            else
            {
                // It was too late to do a clone of the provided ITransactionNative, so we are just going to
                // create a RealOletxTransaction without a transaction shim or outcome enlistment.
                realTx = new RealOletxTransaction(
                    oletxTm,
                    null,
                    null,
                    txIdentifier,
                    OletxTransactionIsolationLevel.ISOLATIONLEVEL_SERIALIZABLE,
                    false );

                oleTx = new OletxTransaction( realTx );
                transaction = new Transaction( oleTx );
                TransactionManager.FireDistributedTransactionStarted( transaction );
                oleTx.savedLtmPromotedTransaction = transaction;

                InternalTransaction.DistributedTransactionOutcome(transaction.internalTransaction, TransactionStatus.InDoubt);
            }


            if ( DiagnosticTrace.Verbose )
            {
                MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    "TransactionInterop.GetTransactionFromDtc"
                    );
            }
            return transaction;
        }
        internal static OletxTransaction GetOletxTransactionFromTransmitterPropigationToken(
            byte[] propagationToken
            )
        {
            Guid identifier;
            OletxTransactionIsolationLevel oletxIsoLevel;
            OutcomeEnlistment outcomeEnlistment;
            ITransactionShim transactionShim = null;

            if ( null == propagationToken )
            {
                throw new ArgumentNullException( "propagationToken" );
            }

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

            byte[] propagationTokenCopy = new byte[propagationToken.Length];
            Array.Copy(propagationToken, propagationTokenCopy, propagationToken.Length);
            propagationToken = propagationTokenCopy;

            // First we need to create an OletxTransactionManager from Config.
            OletxTransactionManager oletxTm = TransactionManager.DistributedTransactionManager;

            oletxTm.dtcTransactionManagerLock.AcquireReaderLock( -1 );
            try
            {
                outcomeEnlistment = new OutcomeEnlistment();
                IntPtr outcomeEnlistmentHandle = IntPtr.Zero;
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                {
                    outcomeEnlistmentHandle = HandleTable.AllocHandle( outcomeEnlistment );
                    oletxTm.DtcTransactionManager.ProxyShimFactory.ReceiveTransaction(
                        Convert.ToUInt32(propagationToken.Length),
                        propagationToken,
                        outcomeEnlistmentHandle,
                        out identifier,
                        out oletxIsoLevel,
                        out transactionShim
                        );
                }
                finally
                {
                    if ( transactionShim == null && outcomeEnlistmentHandle != IntPtr.Zero )
                    {
                        HandleTable.FreeHandle( outcomeEnlistmentHandle );
                    }
                }
            }
            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( SR.GetString( SR.TraceSourceOletx ), comException );
            }
            finally
            {
                oletxTm.dtcTransactionManagerLock.ReleaseReaderLock();
            }

            RealOletxTransaction realTx = null;

            realTx = new RealOletxTransaction(
                oletxTm,
                transactionShim,
                outcomeEnlistment,
                identifier,
                oletxIsoLevel,
                false );
            
            return new OletxTransaction( realTx );
        }
        public static Transaction GetTransactionFromExportCookie(
            byte[] cookie
            )
        {
            if ( !TransactionManager._platformValidated ) TransactionManager.ValidatePlatform();

            if ( null == cookie )
            {
                throw new ArgumentNullException( "cookie" );
            }

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

            if ( DiagnosticTrace.Verbose )
            {
                MethodEnteredTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    "TransactionInterop.GetTransactionFromExportCookie"
                    );
            }

            byte[] cookieCopy = new byte[cookie.Length];
            Array.Copy(cookie, cookieCopy, cookie.Length);
            cookie = cookieCopy;

            Transaction transaction = null;
            ITransactionShim transactionShim = null;
            Guid txIdentifier = Guid.Empty;
            OletxTransactionIsolationLevel oletxIsoLevel = OletxTransactionIsolationLevel.ISOLATIONLEVEL_SERIALIZABLE;
            OutcomeEnlistment outcomeEnlistment = null;
            OletxTransaction oleTx = null;

            // 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 cookie, the transaction guid is preceeded by a signature guid.
                guidByteArray[i] = cookie[i + 16];
            }

            Guid 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 = TransactionManager.FindPromotedTransaction( txId );
            if ( null != transaction )
            {
                if ( DiagnosticTrace.Verbose )
                {
                    MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                        "TransactionInterop.GetTransactionFromExportCookie"
                        );
                }
                return transaction;
            }

            // We need to create a new transaction
            RealOletxTransaction realTx = null;
            OletxTransactionManager oletxTm = TransactionManager.DistributedTransactionManager;

            oletxTm.dtcTransactionManagerLock.AcquireReaderLock( -1 );
            try
            {
                outcomeEnlistment = new OutcomeEnlistment();
                IntPtr outcomeEnlistmentHandle = IntPtr.Zero;
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                {
                    outcomeEnlistmentHandle = HandleTable.AllocHandle( outcomeEnlistment );
                    oletxTm.DtcTransactionManager.ProxyShimFactory.Import(
                        Convert.ToUInt32(cookie.Length),
                        cookie,
                        outcomeEnlistmentHandle,
                        out txIdentifier,
                        out oletxIsoLevel,
                        out transactionShim );
                }
                finally
                {
                    if ( transactionShim == null && outcomeEnlistmentHandle != IntPtr.Zero )
                    {
                        HandleTable.FreeHandle( outcomeEnlistmentHandle );
                    }
                }
            }
            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( SR.GetString( SR.TraceSourceOletx ), comException );
            }
            finally
            {
                oletxTm.dtcTransactionManagerLock.ReleaseReaderLock();
            }

            // We need to create a new RealOletxTransaction.
            realTx = new RealOletxTransaction(
                oletxTm,
                transactionShim,
                outcomeEnlistment,
                txIdentifier,
                oletxIsoLevel,
                false );

            // Now create the associated OletxTransaction.
            oleTx = new OletxTransaction( realTx );

            // If a transaction is found then FindOrCreate will Dispose the oletx
            // created.
            transaction = TransactionManager.FindOrCreatePromotedTransaction( txId, oleTx );

            if ( DiagnosticTrace.Verbose )
            {
                MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    "TransactionInterop.GetTransactionFromExportCookie"
                    );
            }

            return transaction;
        }
Пример #13
0
        internal static void ShimNotificationCallback(object state, bool timeout)
        {
            // First we need to get the notification from the shim factory.
            IntPtr enlistmentHandleIntPtr             = IntPtr.Zero;
            ShimNotificationType shimNotificationType = ShimNotificationType.None;
            bool isSinglePhase = false;
            bool abortingHint  = false;

            UInt32          prepareInfoSize   = 0;
            CoTaskMemHandle prepareInfoBuffer = null;

            bool holdingNotificationLock = false;
            bool cleanExit = false;

            IDtcProxyShimFactory localProxyShimFactory = null;

            if (DiagnosticTrace.Verbose)
            {
                MethodEnteredTraceRecord.Trace(SR.GetString(SR.TraceSourceOletx),
                                               "OletxTransactionManager.ShimNotificationCallback"
                                               );
            }

            // This lock doesn't really protect any of our data.  It is here so that if an exception occurs
            // while calling out to the app, we get an escalation to AppDomainUnload.
            Thread.BeginCriticalRegion();
            try
            {
                do
                {
                    // Take a local copy of the proxyShimFactory because if we get an RM TMDown notification,
                    // we will still hold the critical section in that factory, but processing of the TMDown will
                    // cause replacement of the OletxTransactionManager.proxyShimFactory.
                    localProxyShimFactory = OletxTransactionManager.proxyShimFactory;
                    try
                    {
                        Thread.BeginThreadAffinity();
                        RuntimeHelpers.PrepareConstrainedRegions();
                        try
                        {
                            localProxyShimFactory.GetNotification(
                                out enlistmentHandleIntPtr,
                                out shimNotificationType,
                                out isSinglePhase,
                                out abortingHint,
                                out holdingNotificationLock,
                                out prepareInfoSize,
                                out prepareInfoBuffer
                                );
                        }
                        finally
                        {
                            if (holdingNotificationLock)
                            {
                                if ((HandleTable.FindHandle(enlistmentHandleIntPtr)) is OletxInternalResourceManager)
                                {
                                    // In this case we know that the TM has gone down and we need to exchange
                                    // the native lock for a managed lock.
                                    processingTmDown = true;
#pragma warning disable 0618
                                    //@
                                    System.Threading.Monitor.Enter(OletxTransactionManager.proxyShimFactory);
#pragma warning restore 0618
                                }
                                else
                                {
                                    holdingNotificationLock = false;
                                }
                                localProxyShimFactory.ReleaseNotificationLock();
                            }
                            Thread.EndThreadAffinity();
                        }

                        // If a TM down is being processed it is possible that the native lock
                        // has been exchanged for a managed lock.  In that case we need to attempt
                        // to take a lock to hold up processing more events until the TM down
                        // processing is complete.
                        if (processingTmDown)
                        {
                            lock (OletxTransactionManager.proxyShimFactory)
                            {
                                // We don't do any work under this lock just make sure that we
                                // can take it.
                            }
                        }

                        if (ShimNotificationType.None != shimNotificationType)
                        {
                            Object target = HandleTable.FindHandle(enlistmentHandleIntPtr);

                            // Next, based on the notification type, cast the Handle accordingly and make
                            // the appropriate call on the enlistment.
                            switch (shimNotificationType)
                            {
                            case ShimNotificationType.Phase0RequestNotify:
                            {
                                try
                                {
                                    OletxPhase0VolatileEnlistmentContainer ph0VolEnlistContainer = target as OletxPhase0VolatileEnlistmentContainer;
                                    if (null != ph0VolEnlistContainer)
                                    {
                                        DiagnosticTrace.SetActivityId(
                                            ph0VolEnlistContainer.TransactionIdentifier);
                                        //CSDMain 91509 - We now synchronize this call with the AddDependentClone call in RealOleTxTransaction
                                        ph0VolEnlistContainer.Phase0Request(abortingHint);
                                    }
                                    else
                                    {
                                        OletxEnlistment enlistment = target as OletxEnlistment;
                                        if (null != enlistment)
                                        {
                                            DiagnosticTrace.SetActivityId(
                                                enlistment.TransactionIdentifier);
                                            enlistment.Phase0Request(abortingHint);
                                        }
                                        else
                                        {
                                            Environment.FailFast(SR.GetString(SR.InternalError));
                                        }
                                    }
                                }
                                finally
                                {
                                    // We aren't going to get any more notifications on this.
                                    HandleTable.FreeHandle(enlistmentHandleIntPtr);
                                }
                                break;
                            }

                            case ShimNotificationType.VoteRequestNotify:
                            {
                                OletxPhase1VolatileEnlistmentContainer ph1VolEnlistContainer = target as OletxPhase1VolatileEnlistmentContainer;
                                if (null != ph1VolEnlistContainer)
                                {
                                    DiagnosticTrace.SetActivityId(
                                        ph1VolEnlistContainer.TransactionIdentifier);
                                    ph1VolEnlistContainer.VoteRequest();
                                }
                                else
                                {
                                    Environment.FailFast(SR.GetString(SR.InternalError));
                                }

                                break;
                            }

                            case ShimNotificationType.CommittedNotify:
                            {
                                try
                                {
                                    OutcomeEnlistment outcomeEnlistment = target as OutcomeEnlistment;
                                    if (null != outcomeEnlistment)
                                    {
                                        DiagnosticTrace.SetActivityId(
                                            outcomeEnlistment.TransactionIdentifier);
                                        outcomeEnlistment.Committed();
                                    }
                                    else
                                    {
                                        OletxPhase1VolatileEnlistmentContainer ph1VolEnlistContainer = target as OletxPhase1VolatileEnlistmentContainer;
                                        if (null != ph1VolEnlistContainer)
                                        {
                                            DiagnosticTrace.SetActivityId(
                                                ph1VolEnlistContainer.TransactionIdentifier);
                                            ph1VolEnlistContainer.Committed();
                                        }
                                        else
                                        {
                                            Environment.FailFast(SR.GetString(SR.InternalError));
                                        }
                                    }
                                }
                                finally
                                {
                                    // We aren't going to get any more notifications on this.
                                    HandleTable.FreeHandle(enlistmentHandleIntPtr);
                                }
                                break;
                            }

                            case ShimNotificationType.AbortedNotify:
                            {
                                try
                                {
                                    OutcomeEnlistment outcomeEnlistment = target as OutcomeEnlistment;
                                    if (null != outcomeEnlistment)
                                    {
                                        DiagnosticTrace.SetActivityId(
                                            outcomeEnlistment.TransactionIdentifier);
                                        outcomeEnlistment.Aborted();
                                    }
                                    else
                                    {
                                        OletxPhase1VolatileEnlistmentContainer ph1VolEnlistContainer = target as OletxPhase1VolatileEnlistmentContainer;
                                        if (null != ph1VolEnlistContainer)
                                        {
                                            DiagnosticTrace.SetActivityId(
                                                ph1VolEnlistContainer.TransactionIdentifier);
                                            ph1VolEnlistContainer.Aborted();
                                        }
                                        // else
                                        // Voters may receive notifications even
                                        // in cases where they therwise respond
                                        // negatively to the vote request.  It is
                                        // also not guaranteed that we will get a
                                        // notification if we do respond negatively.
                                        // The only safe thing to do is to free the
                                        // Handle when we abort the transaction
                                        // with a voter.  These two things together
                                        // mean that we cannot guarantee that this
                                        // Handle will be alive when we get this
                                        // notification.
                                    }
                                }
                                finally
                                {
                                    // We aren't going to get any more notifications on this.
                                    HandleTable.FreeHandle(enlistmentHandleIntPtr);
                                }
                                break;
                            }

                            case ShimNotificationType.InDoubtNotify:
                            {
                                try
                                {
                                    OutcomeEnlistment outcomeEnlistment = target as OutcomeEnlistment;
                                    if (null != outcomeEnlistment)
                                    {
                                        DiagnosticTrace.SetActivityId(
                                            outcomeEnlistment.TransactionIdentifier);
                                        outcomeEnlistment.InDoubt();
                                    }
                                    else
                                    {
                                        OletxPhase1VolatileEnlistmentContainer ph1VolEnlistContainer = target as OletxPhase1VolatileEnlistmentContainer;
                                        if (null != ph1VolEnlistContainer)
                                        {
                                            DiagnosticTrace.SetActivityId(
                                                ph1VolEnlistContainer.TransactionIdentifier);
                                            ph1VolEnlistContainer.InDoubt();
                                        }
                                        else
                                        {
                                            Environment.FailFast(SR.GetString(SR.InternalError));
                                        }
                                    }
                                }
                                finally
                                {
                                    // We aren't going to get any more notifications on this.
                                    HandleTable.FreeHandle(enlistmentHandleIntPtr);
                                }
                                break;
                            }

                            case ShimNotificationType.PrepareRequestNotify:
                            {
                                byte[] prepareInfo = new byte[prepareInfoSize];
                                Marshal.Copy(prepareInfoBuffer.DangerousGetHandle(), prepareInfo, 0, Convert.ToInt32(prepareInfoSize));
                                bool enlistmentDone = true;

                                try
                                {
                                    OletxEnlistment enlistment = target as OletxEnlistment;
                                    if (null != enlistment)
                                    {
                                        DiagnosticTrace.SetActivityId(
                                            enlistment.TransactionIdentifier);
                                        enlistmentDone = enlistment.PrepareRequest(
                                            isSinglePhase,
                                            prepareInfo
                                            );
                                    }
                                    else
                                    {
                                        Environment.FailFast(SR.GetString(SR.InternalError));
                                    }
                                }
                                finally
                                {
                                    if (enlistmentDone)
                                    {
                                        HandleTable.FreeHandle(enlistmentHandleIntPtr);
                                    }
                                }

                                break;
                            }

                            case ShimNotificationType.CommitRequestNotify:
                            {
                                try
                                {
                                    OletxEnlistment enlistment = target as OletxEnlistment;
                                    if (null != enlistment)
                                    {
                                        DiagnosticTrace.SetActivityId(
                                            enlistment.TransactionIdentifier);
                                        enlistment.CommitRequest();
                                    }
                                    else
                                    {
                                        Environment.FailFast(SR.GetString(SR.InternalError));
                                    }
                                }
                                finally
                                {
                                    // We aren't going to get any more notifications on this.
                                    HandleTable.FreeHandle(enlistmentHandleIntPtr);
                                }

                                break;
                            }

                            case ShimNotificationType.AbortRequestNotify:
                            {
                                try
                                {
                                    OletxEnlistment enlistment = target as OletxEnlistment;
                                    if (null != enlistment)
                                    {
                                        DiagnosticTrace.SetActivityId(
                                            enlistment.TransactionIdentifier);
                                        enlistment.AbortRequest();
                                    }
                                    else
                                    {
                                        Environment.FailFast(SR.GetString(SR.InternalError));
                                    }
                                }
                                finally
                                {
                                    // We aren't going to get any more notifications on this.
                                    HandleTable.FreeHandle(enlistmentHandleIntPtr);
                                }

                                break;
                            }

                            case ShimNotificationType.EnlistmentTmDownNotify:
                            {
                                try
                                {
                                    OletxEnlistment enlistment = target as OletxEnlistment;
                                    if (null != enlistment)
                                    {
                                        DiagnosticTrace.SetActivityId(
                                            enlistment.TransactionIdentifier);
                                        enlistment.TMDown();
                                    }
                                    else
                                    {
                                        Environment.FailFast(SR.GetString(SR.InternalError));
                                    }
                                }
                                finally
                                {
                                    // We aren't going to get any more notifications on this.
                                    HandleTable.FreeHandle(enlistmentHandleIntPtr);
                                }

                                break;
                            }


                            case ShimNotificationType.ResourceManagerTmDownNotify:
                            {
                                OletxResourceManager resourceManager = target as OletxResourceManager;
                                try
                                {
                                    if (null != resourceManager)
                                    {
                                        resourceManager.TMDown();
                                    }
                                    else
                                    {
                                        OletxInternalResourceManager internalResourceManager = target as OletxInternalResourceManager;
                                        if (null != internalResourceManager)
                                        {
                                            internalResourceManager.TMDown();
                                        }
                                        else
                                        {
                                            Environment.FailFast(SR.GetString(SR.InternalError));
                                        }
                                    }
                                }
                                finally
                                {
                                    HandleTable.FreeHandle(enlistmentHandleIntPtr);
                                }

                                // Note that we don't free the gchandle on the OletxResourceManager.  These objects
                                // are not going to go away.
                                break;
                            }

                            default:
                            {
                                Environment.FailFast(SR.GetString(SR.InternalError));
                                break;
                            }
                            }
                        }
                    }
                    finally
                    {
                        if (null != prepareInfoBuffer)
                        {
                            prepareInfoBuffer.Close();
                        }

                        if (holdingNotificationLock)
                        {
                            holdingNotificationLock = false;
                            processingTmDown        = false;
                            System.Threading.Monitor.Exit(OletxTransactionManager.proxyShimFactory);
                        }
                    }
                }while (ShimNotificationType.None != shimNotificationType);

                cleanExit = true;
            }
            finally
            {
                if (holdingNotificationLock)
                {
                    holdingNotificationLock = false;
                    processingTmDown        = false;
                    System.Threading.Monitor.Exit(OletxTransactionManager.proxyShimFactory);
                }

                if (!cleanExit && enlistmentHandleIntPtr != IntPtr.Zero)
                {
                    HandleTable.FreeHandle(enlistmentHandleIntPtr);
                }

                Thread.EndCriticalRegion();
            }

            if (DiagnosticTrace.Verbose)
            {
                MethodExitedTraceRecord.Trace(SR.GetString(SR.TraceSourceOletx),
                                              "OletxTransactionManager.ShimNotificationCallback"
                                              );
            }
        }
Пример #14
0
        internal OletxCommittableTransaction CreateTransaction(
            TransactionOptions properties
            )
        {
            OletxCommittableTransaction tx = null;
            RealOletxTransaction        realTransaction = null;
            ITransactionShim            transactionShim = null;
            Guid txIdentifier = Guid.Empty;
            OutcomeEnlistment outcomeEnlistment = null;

            // Demand the distributed transation permission to create one of
            // these.
            DistributedTransactionPermission txPerm =
                new DistributedTransactionPermission(PermissionState.Unrestricted);

            txPerm.Demand();

            TransactionManager.ValidateIsolationLevel(properties.IsolationLevel);

            // Never create a transaction with an IsolationLevel of Unspecified.
            if (IsolationLevel.Unspecified == properties.IsolationLevel)
            {
                properties.IsolationLevel = configuredTransactionOptions.IsolationLevel;
            }

            properties.Timeout = TransactionManager.ValidateTimeout(properties.Timeout);

            this.dtcTransactionManagerLock.AcquireReaderLock(-1);
            try
            {
                //
                OletxTransactionIsolationLevel oletxIsoLevel = OletxTransactionManager.ConvertIsolationLevel(properties.IsolationLevel);
                UInt32 oletxTimeout = DtcTransactionManager.AdjustTimeout(properties.Timeout);

                outcomeEnlistment = new OutcomeEnlistment();
                IntPtr outcomeEnlistmentHandle = IntPtr.Zero;
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                {
                    outcomeEnlistmentHandle = HandleTable.AllocHandle(outcomeEnlistment);

                    dtcTransactionManager.ProxyShimFactory.BeginTransaction(
                        oletxTimeout,
                        oletxIsoLevel,
                        outcomeEnlistmentHandle,
                        out txIdentifier,
                        out transactionShim
                        );
                }
                catch (COMException ex)
                {
                    OletxTransactionManager.ProxyException(ex);
                    throw;
                }
                finally
                {
                    if (transactionShim == null && outcomeEnlistmentHandle != IntPtr.Zero)
                    {
                        HandleTable.FreeHandle(outcomeEnlistmentHandle);
                    }
                }

                realTransaction = new RealOletxTransaction(
                    this,
                    transactionShim,
                    outcomeEnlistment,
                    txIdentifier,
                    oletxIsoLevel,
                    true
                    );
                tx = new OletxCommittableTransaction(realTransaction);
                if (DiagnosticTrace.Information)
                {
                    TransactionCreatedTraceRecord.Trace(SR.GetString(SR.TraceSourceOletx),
                                                        tx.TransactionTraceId
                                                        );
                }
            }
            finally
            {
                this.dtcTransactionManagerLock.ReleaseReaderLock();
            }

            return(tx);
        }
Пример #15
0
        internal OletxCommittableTransaction CreateTransaction(
            TransactionOptions properties
            )
        {
            OletxCommittableTransaction tx = null;
            RealOletxTransaction realTransaction = null;
            ITransactionShim transactionShim = null;
            Guid txIdentifier = Guid.Empty;
            OutcomeEnlistment outcomeEnlistment = null;

            // Demand the distributed transation permission to create one of
            // these.
            DistributedTransactionPermission txPerm = 
                new DistributedTransactionPermission( PermissionState.Unrestricted );
            txPerm.Demand();

            TransactionManager.ValidateIsolationLevel( properties.IsolationLevel );

            // Never create a transaction with an IsolationLevel of Unspecified.
            if ( IsolationLevel.Unspecified == properties.IsolationLevel )
            {
                properties.IsolationLevel = configuredTransactionOptions.IsolationLevel;
            }

            properties.Timeout = TransactionManager.ValidateTimeout( properties.Timeout );

            this.dtcTransactionManagerLock.AcquireReaderLock( -1 );
            try
            {
                // 
                OletxTransactionIsolationLevel oletxIsoLevel = OletxTransactionManager.ConvertIsolationLevel( properties.IsolationLevel );
                UInt32 oletxTimeout = DtcTransactionManager.AdjustTimeout( properties.Timeout );

                outcomeEnlistment = new OutcomeEnlistment();
                IntPtr outcomeEnlistmentHandle = IntPtr.Zero;
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                {
                    outcomeEnlistmentHandle = HandleTable.AllocHandle( outcomeEnlistment );
                    
                    dtcTransactionManager.ProxyShimFactory.BeginTransaction(
                        oletxTimeout,
                        oletxIsoLevel,
                        outcomeEnlistmentHandle,
                        out txIdentifier,
                        out transactionShim
                        );
                }
                catch ( COMException ex )
                {
                    OletxTransactionManager.ProxyException( ex );
                    throw;
                }
                finally
                {
                    if ( transactionShim == null && outcomeEnlistmentHandle != IntPtr.Zero )
                    {
                        HandleTable.FreeHandle( outcomeEnlistmentHandle );
                    }
                }

                realTransaction = new RealOletxTransaction( 
                    this,
                    transactionShim,
                    outcomeEnlistment,
                    txIdentifier,
                    oletxIsoLevel,
                    true
                    );
                tx = new OletxCommittableTransaction( realTransaction );
                if ( DiagnosticTrace.Information )
                {
                    TransactionCreatedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                        tx.TransactionTraceId
                        );
                }
            }
            finally
            {
                this.dtcTransactionManagerLock.ReleaseReaderLock();
            }

            return tx;

        }