Beispiel #1
0
        internal static IsolationLevel ConvertIsolationLevelFromProxyValue(OletxTransactionIsolationLevel proxyIsolationLevel)
        {
            OletxTransactionIsolationLevel level2 = proxyIsolationLevel;

            if (level2 <= OletxTransactionIsolationLevel.ISOLATIONLEVEL_READUNCOMMITTED)
            {
                switch (level2)
                {
                case OletxTransactionIsolationLevel.ISOLATIONLEVEL_UNSPECIFIED:
                    return(IsolationLevel.Unspecified);

                case OletxTransactionIsolationLevel.ISOLATIONLEVEL_CHAOS:
                    return(IsolationLevel.Chaos);

                case OletxTransactionIsolationLevel.ISOLATIONLEVEL_READUNCOMMITTED:
                    return(IsolationLevel.ReadUncommitted);
                }
            }
            else if (level2 != OletxTransactionIsolationLevel.ISOLATIONLEVEL_CURSORSTABILITY)
            {
                if (level2 == OletxTransactionIsolationLevel.ISOLATIONLEVEL_REPEATABLEREAD)
                {
                    return(IsolationLevel.RepeatableRead);
                }
                if (level2 == OletxTransactionIsolationLevel.ISOLATIONLEVEL_SERIALIZABLE)
                {
                    return(IsolationLevel.Serializable);
                }
            }
            else
            {
                return(IsolationLevel.ReadCommitted);
            }
            return(IsolationLevel.Serializable);
        }
Beispiel #2
0
 internal OletxXactTransInfo(Guid guid, OletxTransactionIsolationLevel isoLevel)
 {
     this.uow                     = guid;
     this.isoLevel                = isoLevel;
     this.isoFlags                = OletxTransactionIsoFlags.ISOFLAG_NONE;
     this.grfTCSupported          = 0;
     this.grfRMSupported          = 0;
     this.grfTCSupportedRetaining = 0;
     this.grfRMSupportedRetaining = 0;
 }
 internal OletxXactTransInfo(Guid guid, OletxTransactionIsolationLevel isoLevel)
 {
     this.uow = guid;
     this.isoLevel = isoLevel;
     this.isoFlags = OletxTransactionIsoFlags.ISOFLAG_NONE;
     this.grfTCSupported = 0;
     this.grfRMSupported = 0;
     this.grfTCSupportedRetaining = 0;
     this.grfRMSupportedRetaining = 0;
 }
Beispiel #4
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;
         }
     }
 }
Beispiel #6
0
        internal static IsolationLevel ConvertIsolationLevelFromProxyValue(OletxTransactionIsolationLevel proxyIsolationLevel)
        {
            IsolationLevel retVal;

            switch (proxyIsolationLevel)
            {
            case OletxTransactionIsolationLevel.ISOLATIONLEVEL_SERIALIZABLE:
                retVal = IsolationLevel.Serializable;
                break;

            case OletxTransactionIsolationLevel.ISOLATIONLEVEL_REPEATABLEREAD:
                retVal = IsolationLevel.RepeatableRead;
                break;

            case OletxTransactionIsolationLevel.ISOLATIONLEVEL_READCOMMITTED:
                retVal = IsolationLevel.ReadCommitted;
                break;

            case OletxTransactionIsolationLevel.ISOLATIONLEVEL_READUNCOMMITTED:
                retVal = IsolationLevel.ReadUncommitted;
                break;

            case OletxTransactionIsolationLevel.ISOLATIONLEVEL_UNSPECIFIED:
                retVal = IsolationLevel.Unspecified;
                break;

            case OletxTransactionIsolationLevel.ISOLATIONLEVEL_CHAOS:
                retVal = IsolationLevel.Chaos;
                break;

            default:
                retVal = IsolationLevel.Serializable;
                break;
            }
            return(retVal);
        }
        internal static IsolationLevel ConvertIsolationLevelFromProxyValue(OletxTransactionIsolationLevel proxyIsolationLevel)
        {
            OletxTransactionIsolationLevel level2 = proxyIsolationLevel;
            if (level2 <= OletxTransactionIsolationLevel.ISOLATIONLEVEL_READUNCOMMITTED)
            {
                switch (level2)
                {
                    case OletxTransactionIsolationLevel.ISOLATIONLEVEL_UNSPECIFIED:
                        return IsolationLevel.Unspecified;

                    case OletxTransactionIsolationLevel.ISOLATIONLEVEL_CHAOS:
                        return IsolationLevel.Chaos;

                    case OletxTransactionIsolationLevel.ISOLATIONLEVEL_READUNCOMMITTED:
                        return IsolationLevel.ReadUncommitted;
                }
            }
            else if (level2 != OletxTransactionIsolationLevel.ISOLATIONLEVEL_CURSORSTABILITY)
            {
                if (level2 == OletxTransactionIsolationLevel.ISOLATIONLEVEL_REPEATABLEREAD)
                {
                    return IsolationLevel.RepeatableRead;
                }
                if (level2 == OletxTransactionIsolationLevel.ISOLATIONLEVEL_SERIALIZABLE)
                {
                    return IsolationLevel.Serializable;
                }
            }
            else
            {
                return IsolationLevel.ReadCommitted;
            }
            return IsolationLevel.Serializable;
        }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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);
        }
Beispiel #11
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;
                    }
                }
            }
               
        }
        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;
                }
            }
        }
Beispiel #13
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);
        }
 internal static IsolationLevel ConvertIsolationLevelFromProxyValue( OletxTransactionIsolationLevel proxyIsolationLevel )
 {
     IsolationLevel retVal;
     switch (proxyIsolationLevel)
     {
         case OletxTransactionIsolationLevel.ISOLATIONLEVEL_SERIALIZABLE:
             retVal = IsolationLevel.Serializable;
             break;
         case OletxTransactionIsolationLevel.ISOLATIONLEVEL_REPEATABLEREAD:
             retVal = IsolationLevel.RepeatableRead;
             break;
         case OletxTransactionIsolationLevel.ISOLATIONLEVEL_READCOMMITTED:
             retVal = IsolationLevel.ReadCommitted;
             break;
         case OletxTransactionIsolationLevel.ISOLATIONLEVEL_READUNCOMMITTED:
             retVal = IsolationLevel.ReadUncommitted;
             break;
         case OletxTransactionIsolationLevel.ISOLATIONLEVEL_UNSPECIFIED:
             retVal = IsolationLevel.Unspecified;
             break;
         case OletxTransactionIsolationLevel.ISOLATIONLEVEL_CHAOS:
             retVal = IsolationLevel.Chaos;
             break;
         default:
             retVal = IsolationLevel.Serializable;
             break;
     }
     return retVal;
 }
Beispiel #15
0
        public static Transaction GetTransactionFromDtcTransaction(IDtcTransaction transactionNative)
        {
            ArgumentNullException.ThrowIfNull(transactionNative, nameof(transactionNative));

            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

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

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

            // Let's get the guid of the transaction from the proxy to see if we already have an object.
            if (transactionNative is not ITransaction myTransactionNative)
            {
                throw new ArgumentException(SR.InvalidArgument, nameof(transactionNative));
            }

            OletxXactTransInfo xactInfo;

            try
            {
                myTransactionNative.GetTransactionInfo(out xactInfo);
            }
            catch (COMException ex) when(ex.ErrorCode == OletxHelper.XACT_E_NOTRANSACTION)
            {
                // 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 (transaction != null)
                {
                    if (etwLog.IsEnabled())
                    {
                        etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, $"{nameof(TransactionInterop)}.{nameof(GetTransactionFromDtcTransaction)}");
                    }

                    return(transaction);
                }

                // We need to create a new RealOletxTransaction...
                oletxTm.DtcTransactionManagerLock.AcquireReaderLock(-1);
                try
                {
                    outcomeEnlistment = new OutcomeEnlistment();
                    oletxTm.DtcTransactionManager.ProxyShimFactory.CreateTransactionShim(
                        transactionNative,
                        outcomeEnlistment,
                        out txIdentifier,
                        out oletxIsoLevel,
                        out transactionShim);
                }
                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 (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, $"{nameof(TransactionInterop)}.{nameof(GetTransactionFromDtcTransaction)}");
            }

            return(transaction);
        }
Beispiel #16
0
        public static Transaction GetTransactionFromExportCookie(byte[] cookie)
        {
            ArgumentNullException.ThrowIfNull(cookie);

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

            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

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

            var cookieCopy = new byte[cookie.Length];

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

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

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

            // First check to see if there is a promoted LTM transaction with the same ID.  If there
            // is, just return that.
            transaction = TransactionManager.FindPromotedTransaction(txId);
            if (transaction != null)
            {
                if (etwLog.IsEnabled())
                {
                    etwLog.MethodExit(TraceSourceType.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();
                oletxTm.DtcTransactionManager.ProxyShimFactory.Import(cookie, outcomeEnlistment, out txIdentifier, out oletxIsoLevel, out transactionShim);
            }
            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.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 (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceOleTx, $"{nameof(TransactionInterop)}.{nameof(GetTransactionFromExportCookie)}");
            }

            return(transaction);
        }
Beispiel #17
0
        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);
        }