Пример #1
0
        internal static Transaction FastGetTransaction(TransactionScope currentScope, ContextData contextData, out Transaction contextTransaction)
        {
            Transaction current = null;
            contextTransaction = null;

            contextTransaction = contextData.CurrentTransaction;

            switch (InteropMode(currentScope))
            {
                case EnterpriseServicesInteropOption.None:

                    current = contextTransaction;

                    // If there is a transaction in the execution context or if there is a current transaction scope
                    // then honer the transaction context.
                    if (current == null && currentScope == null)
                    {
                        // Otherwise check for an external current.
                        if (TransactionManager.s_currentDelegateSet)
                        {
                            current = TransactionManager.s_currentDelegate();
                        }
                        else
                        {
                            current = EnterpriseServices.GetContextTransaction(contextData);
                        }
                    }
                    break;

                case EnterpriseServicesInteropOption.Full:
                    current = EnterpriseServices.GetContextTransaction(contextData);
                    break;

                case EnterpriseServicesInteropOption.Automatic:
                    if (EnterpriseServices.UseServiceDomainForCurrent())
                    {
                        current = EnterpriseServices.GetContextTransaction(contextData);
                    }
                    else
                    {
                        current = contextData.CurrentTransaction;
                    }
                    break;
            }

            return current;
        }
Пример #2
0
        internal static Transaction?FastGetTransaction(TransactionScope?currentScope, ContextData contextData, out Transaction?contextTransaction)
        {
            Transaction?current = null;

            contextTransaction = null;

            contextTransaction = contextData.CurrentTransaction;

            switch (InteropMode(currentScope))
            {
            case EnterpriseServicesInteropOption.None:

                current = contextTransaction;

                // If there is a transaction in the execution context or if there is a current transaction scope
                // then honer the transaction context.
                if (current == null && currentScope == null)
                {
                    // Otherwise check for an external current.
                    if (TransactionManager.s_currentDelegateSet)
                    {
                        current = TransactionManager.s_currentDelegate !();
                    }
                    else
                    {
                        current = EnterpriseServices.GetContextTransaction(contextData);
                    }
                }
                break;

            case EnterpriseServicesInteropOption.Full:
                current = EnterpriseServices.GetContextTransaction(contextData);
                break;

            case EnterpriseServicesInteropOption.Automatic:
                if (EnterpriseServices.UseServiceDomainForCurrent())
                {
                    current = EnterpriseServices.GetContextTransaction(contextData);
                }
                else
                {
                    current = contextData.CurrentTransaction;
                }
                break;
            }

            return(current);
        }
Пример #3
0
 // GetContextTransaction
 //
 // Get a transaction from Com+ through EnterpriseServices
 internal static Transaction GetContextTransaction(ContextData contextData)
 {
     if (EnterpriseServicesOk)
     {
         return JitSafeGetContextTransaction(contextData);
     }
     return null;
 }
Пример #4
0
        private static Transaction JitSafeGetContextTransaction(ContextData contextData)
        {
            // Attempt to see if we are in the default context in which case we don't need to 
            // call SystemTransaction at all.
            SafeIUnknown defaultContext = null;

            if (contextData.WeakDefaultComContext != null)
            {
                defaultContext = (SafeIUnknown)contextData.WeakDefaultComContext.Target;
            }
            
            if (contextData.DefaultComContextState == DefaultComContextState.Unknown ||
                (contextData.DefaultComContextState == DefaultComContextState.Available &&
                 defaultContext == null)
              )
            {
                try
                {
                    NativeMethods.CoGetDefaultContext(-1, ref IID_IObjContext, out defaultContext);
                    contextData.WeakDefaultComContext = new WeakReference(defaultContext);
                    contextData.DefaultComContextState = DefaultComContextState.Available;
                }
                catch (System.EntryPointNotFoundException e)
                {
                    if (DiagnosticTrace.Verbose)
                    {
                        ExceptionConsumedTraceRecord.Trace(SR.GetString(SR.TraceSourceBase),
                            e);
                    }
                    contextData.DefaultComContextState = DefaultComContextState.Unavailable;
                }
            }

            if (contextData.DefaultComContextState == DefaultComContextState.Available)
            {
                IntPtr contextToken = IntPtr.Zero;
                NativeMethods.CoGetContextToken(out contextToken);

                // Check to see if the context token is the default context.
                if (defaultContext.DangerousGetHandle() == contextToken)
                {
                    return null;
                }
            }
            

#if USE_ISINTRANSACTION
            if (!SysES.ContextUtil.IsInTransaction)
            {
                return null;
            }
#endif

            return (Transaction)SysES.ContextUtil.SystemTransaction;
        }
Пример #5
0
 static public bool TryGetCurrentData(out ContextData currentData)
 {
     currentData = null;
     ContextKey contextKey = (ContextKey)CallContext.LogicalGetData(CurrentTransactionProperty);
     if (contextKey == null)
     {
        return false;
     }
     else
     {
        return ContextDataTable.TryGetValue(contextKey, out currentData);
     }
 }
 internal static void GetCurrentTransactionAndScope(out Transaction current, out TransactionScope currentScope, out ContextData contextData, out Transaction contextTransaction)
 {
     contextData  = ContextData.CurrentData;
     currentScope = contextData.CurrentScope;
     current      = FastGetTransaction(currentScope, contextData, out contextTransaction);
 }
Пример #7
0
 public static bool TryGetCurrentData(out ContextData currentData)
 {
     currentData = null;
     ContextKey contextKey = s_currentTransaction.Value;
     if (contextKey == null)
     {
         return false;
     }
     else
     {
         return s_contextDataTable.TryGetValue(contextKey, out currentData);
     }
 }
 private static Transaction JitSafeGetContextTransaction(ContextData contextData)
 {
     SafeIUnknown safeUnknown = null;
     if (contextData.WeakDefaultComContext != null)
     {
         safeUnknown = (SafeIUnknown) contextData.WeakDefaultComContext.Target;
     }
     if ((contextData.DefaultComContextState == DefaultComContextState.Unknown) || ((contextData.DefaultComContextState == DefaultComContextState.Available) && (safeUnknown == null)))
     {
         try
         {
             System.Transactions.NativeMethods.CoGetDefaultContext(-1, ref IID_IObjContext, out safeUnknown);
             contextData.WeakDefaultComContext = new WeakReference(safeUnknown);
             contextData.DefaultComContextState = DefaultComContextState.Available;
         }
         catch (EntryPointNotFoundException exception)
         {
             if (DiagnosticTrace.Verbose)
             {
                 ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceBase"), exception);
             }
             contextData.DefaultComContextState = DefaultComContextState.Unavailable;
         }
     }
     if (contextData.DefaultComContextState == DefaultComContextState.Available)
     {
         IntPtr zero = IntPtr.Zero;
         System.Transactions.NativeMethods.CoGetContextToken(out zero);
         if (safeUnknown.DangerousGetHandle() == zero)
         {
             return null;
         }
     }
     if (!ContextUtil.IsInTransaction)
     {
         return null;
     }
     return ContextUtil.SystemTransaction;
 }
        internal static Transaction FastGetTransaction(TransactionScope currentScope, ContextData contextData, out Transaction contextTransaction)
        {
            Transaction transaction = null;

            contextTransaction = null;
            contextTransaction = contextData.CurrentTransaction;
            switch (InteropMode(currentScope))
            {
            case EnterpriseServicesInteropOption.None:
                transaction = contextTransaction;
                if ((transaction == null) && (currentScope == null))
                {
                    if (!TransactionManager.currentDelegateSet)
                    {
                        return(GetContextTransaction(contextData));
                    }
                    transaction = TransactionManager.currentDelegate();
                }
                return(transaction);

            case EnterpriseServicesInteropOption.Automatic:
                if (!UseServiceDomainForCurrent())
                {
                    return(contextData.CurrentTransaction);
                }
                return(GetContextTransaction(contextData));

            case EnterpriseServicesInteropOption.Full:
                return(GetContextTransaction(contextData));
            }
            return(transaction);
        }
 internal static void GetCurrentTransactionAndScope(out Transaction current, out TransactionScope currentScope, out ContextData contextData, out Transaction contextTransaction)
 {
     contextData = ContextData.CurrentData;
     currentScope = contextData.CurrentScope;
     current = FastGetTransaction(currentScope, contextData, out contextTransaction);
 }
        internal static Transaction FastGetTransaction(TransactionScope currentScope, ContextData contextData, out Transaction contextTransaction)
        {
            Transaction transaction = null;
            contextTransaction = null;
            contextTransaction = contextData.CurrentTransaction;
            switch (InteropMode(currentScope))
            {
                case EnterpriseServicesInteropOption.None:
                    transaction = contextTransaction;
                    if ((transaction == null) && (currentScope == null))
                    {
                        if (!TransactionManager.currentDelegateSet)
                        {
                            return GetContextTransaction(contextData);
                        }
                        transaction = TransactionManager.currentDelegate();
                    }
                    return transaction;

                case EnterpriseServicesInteropOption.Automatic:
                    if (!UseServiceDomainForCurrent())
                    {
                        return contextData.CurrentTransaction;
                    }
                    return GetContextTransaction(contextData);

                case EnterpriseServicesInteropOption.Full:
                    return GetContextTransaction(contextData);
            }
            return transaction;
        }
Пример #12
0
        private void SaveTLSContextData()
        {
            if (_savedTLSContextData == null)
            {
                _savedTLSContextData = new ContextData(false);
            }

            _savedTLSContextData.CurrentScope = ContextData.TLSCurrentData.CurrentScope;
            _savedTLSContextData.CurrentTransaction = ContextData.TLSCurrentData.CurrentTransaction;
            _savedTLSContextData.DefaultComContextState = ContextData.TLSCurrentData.DefaultComContextState;
            _savedTLSContextData.WeakDefaultComContext = ContextData.TLSCurrentData.WeakDefaultComContext;
        }
Пример #13
0
        // PopScope
        //
        // Pop the current transaction scope off the top of the stack
        private void PopScope()
        {
            bool shouldRestoreContextData = true;

            // Clear the current TransactionScope CallContext data
            if (AsyncFlowEnabled)
            {
                CallContextCurrentData.ClearCurrentData(ContextKey, true);
            }

            if (_scopeThread == Thread.CurrentThread)
            {
                // async function yield at await points and main thread can continue execution. We need to make sure the TLS data are restored appropriately.
                // Restore the TLS only if the thread Ids match.
                RestoreSavedTLSContextData();
            }

            // Restore threadContextData to parent CallContext or TLS data
            if (_savedCurrentScope != null)
            {
                if (_savedCurrentScope.AsyncFlowEnabled)
                {
                    _threadContextData = CallContextCurrentData.CreateOrGetCurrentData(_savedCurrentScope.ContextKey);
                }
                else
                {
                    if (_savedCurrentScope._scopeThread != Thread.CurrentThread)
                    {
                        // Clear TLS data so that transaction doesn't leak from current thread.
                        shouldRestoreContextData = false;
                        ContextData.TLSCurrentData = null;
                    }
                    else
                    {
                        _threadContextData = ContextData.TLSCurrentData;
                    }

                    CallContextCurrentData.ClearCurrentData(_savedCurrentScope.ContextKey, false);
                }
            }
            else
            {
                // No parent TransactionScope present

                // Clear any CallContext data
                CallContextCurrentData.ClearCurrentData(null, false);

                if (_scopeThread != Thread.CurrentThread)
                {
                    // Clear TLS data so that transaction doesn't leak from current thread.
                    shouldRestoreContextData = false;
                    ContextData.TLSCurrentData = null;
                }
                else
                {
                    // Restore the current data to TLS.
                    ContextData.TLSCurrentData = _threadContextData;
                }
            }

            // prevent restoring the context in an unexpected thread due to thread switch during TransactionScope's Dispose
            if (shouldRestoreContextData)
            {
                _threadContextData.CurrentScope = _savedCurrentScope;
                RestoreCurrent();
            }
        }
Пример #14
0
        // PushScope
        //
        // Push a transaction scope onto the stack.
        private void PushScope()
        {
            // Fixup the interop mode before we set current.
            if (!_interopModeSpecified)
            {
                // Transaction.InteropMode will take the interop mode on
                // for the scope in currentScope into account.
                _interopOption = Transaction.InteropMode(_savedCurrentScope);
            }

            // async function yield at await points and main thread can continue execution. We need to make sure the TLS data are restored appropriately.
            SaveTLSContextData();

            if (AsyncFlowEnabled)
            {
                // Async Flow is enabled and CallContext will be used for ambient transaction.
                _threadContextData = CallContextCurrentData.CreateOrGetCurrentData(ContextKey);

                if (_savedCurrentScope == null && _savedCurrent == null)
                {
                    // Clear TLS data so that transaction doesn't leak from current thread.
                    ContextData.TLSCurrentData = null;
                }
            }
            else
            {
                // Legacy TransactionScope. Use TLS to track ambient transaction context.
                _threadContextData = ContextData.TLSCurrentData;
                CallContextCurrentData.ClearCurrentData(ContextKey, false);
            }

            // This call needs to be done first
            SetCurrent(_expectedCurrent);
            _threadContextData.CurrentScope = this;
        }