ASP.NET和ThreadStatic是TransactionScope实现的一部分

Fab*_*bio 7 asp.net transactionscope threadstatic

我想知道TransactionScope类如何工作以保持不同方法调用之间的事务(不需要将其作为参数传递),我开始怀疑.我对这个问题有两点考虑:

1

通过Telerik JustDecompile查看TransactionScope的实现,我发现当前事务存储在System.Transactions.ContextData类的ThreadStatic成员中(下面的代码).

internal class ContextData
{
    internal TransactionScope CurrentScope;

    internal Transaction CurrentTransaction;

    internal DefaultComContextState DefaultComContextState;

    [ThreadStatic]
    private static ContextData staticData;

    internal WeakReference WeakDefaultComContext;

    internal static ContextData CurrentData
    {
        get
        {
            ContextData contextDatum = ContextData.staticData;
            if (contextDatum == null)
            {
                contextDatum = new ContextData();
                ContextData.staticData = contextDatum;
            }
            return contextDatum;
        }
    }

    public ContextData()
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

CurrentData属性由TransactionScope的PushScope()方法调用,最后一个属性由大多数TransactionScope构造函数使用.

private void PushScope()
{
    if (!this.interopModeSpecified)
    {
        this.interopOption = Transaction.InteropMode(this.savedCurrentScope);
    }
    this.SetCurrent(this.expectedCurrent);
    this.threadContextData.CurrentScope = this;
}

public TransactionScope(TransactionScopeOption scopeOption)
{
    // ...
    this.PushScope();
    // ...
}
Run Code Online (Sandbox Code Playgroud)

好吧,我想我已经找到了他们是如何做到的.

2

我已经读过由于可能发生的ASP.NET线程切换而使用ThreadStatic成员在ASP.NET(http://www.hanselman.com/blog/ATaleOfTwoTechniquesTheThreadStaticAttributeAndSystemWebHttpContextCurrentItems.aspx)中存储对象有多糟糕,因此这些数据可以在工作线程中丢失.

因此,看起来TransactionScope不适用于ASP.NET,对吧?但到目前为止,我已经在我的Web应用程序中使用它,我不记得有任何关于交易数据丢失的问题.

我的问题是"什么是TransactionScope处理ASP.NET线程切换的技巧?".

我是否对TransactionScope如何存储其事务对象进行了肤浅的分析?或者TransactionScope类没有与ASP.NET一起工作,我可以被认为是一个从未有过任何痛苦的幸运家伙?

任何知道.NET的"深埋秘密"的人都可以解释一下吗?

谢谢

Vin*_*ayC 1

我相信 ASP.NET 线程切换仅发生在特定情况(涉及异步 IO 操作)和请求生命周期的早期。通常,一旦控制权传递到实际的 http 处理程序(例如 Page),线程就不会切换。我相信在大多数情况下,事务范围只会在那之后(在 page_init/load 之后)初始化,并且不应该成为问题。

以下是您可能感兴趣的一些链接:

http://piers7.blogspot.com/2005/11/threadstatic-callcontext-and_02.html

http://piers7.blogspot.com/2005/12/log4net-context-problems-with-aspnet.html