ASP.NET и ThreadStatic как часть реализации TransactionScope - PullRequest
7 голосов
/ 19 сентября 2011

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

1

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

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

Мой вопрос здесь таков:Уловка ansactionScope для работы с переключением потоков ASP.NET? ".

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

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

Спасибо

1 Ответ

1 голос
/ 19 сентября 2011

Я полагаю, что переключение потоков ASP.NET происходит только в определенных ситуациях (включая асинхронные операции ввода-вывода) и в начале жизненного цикла запроса. Как правило, когда управление передается фактическому обработчику 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

...