ASP.NET и ThreadStatic как часть реализации TransactionScope

Мне было интересно, как работает класс TransactionScope, чтобы поддерживать транзакцию между вызовами разных методов (без необходимости передавать ее в качестве параметра), и я пришел к этому сомнению. У меня есть два соображения по поводу этого вопроса:

1

Изучая реализацию TransactionScope через Telerik JustDecompile, я обнаружил, что текущая транзакция хранится в члене ThreadStatic класса System.Transactions.ContextData (код ниже ).

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 вызывается методом PushScope () TransactionScope, а последний из них используется большинством конструкторов 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, верно? Но поскольку я использовал его в своих веб-приложениях, я не помню ни одной проблемы, с которой я столкнулся, из-за потери данных транзакции.

У меня вопрос: «Какая уловка TransactionScope справляется с переключением потоков ASP.NET?».

Провел ли я поверхностный анализ того, как TransactionScope хранит свои объекты транзакций? Или класс TransactionScope не был создан для работы с ASP.NET, и меня можно считать счастливчиком, у которого никогда не было проблем?

Может ли кто-нибудь, кто знает «очень глубоко скрытые секреты» .NET, объяснить это для мне?

Спасибо

7
задан Fabio 19 September 2011 в 02:37
поделиться