7

我想知道 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()
    {
    }
}

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();
    // ...
}

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

2

我已经了解了使用 ThreadStatic 成员在 ASP.NET (http://www.hanselman.com/blog/ATaleOfTwoTechniquesTheThreadStaticAttributeAndSystemWebHttpContextCurrentItems.aspx) 中存储对象有多糟糕,因为可能会发生 ASP.NET 线程切换,所以这个数据可能会在工作线程中丢失。

所以,看起来 TransactionScope 不应该与 ASP.NET 一起工作,对吧?但就我在我的 Web 应用程序中使用它而言,我不记得我遇到过有关事务数据丢失的任何问题。

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

是不是对 TransactionScope 是如何存储其事务对象进行了粗浅的分析?或者 TransactionScope 类没有与 ASP.NET 一起工作,我可以被认为是一个从未为此感到痛苦的幸运儿?

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

谢谢

4

1 回答 1

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

于 2011-09-19T05:40:37.697 回答