Хороший способ управления DataContext в ASP.NET? SqlException: серверу не удалось возобновить транзакцию - PullRequest
1 голос
/ 29 августа 2011

Мы создаем один Linq2Sql DataContext для каждого запроса, используя следующий класс:

public static class DataContextManager
{

    private const string HTTPCONTEXT_KEY = "DataContextManagerKey";

    private static CompanyDataContext _staticContext; //when there's no HttpContext (in test/debug situations). 

    public static CompanyDataContext Context
    {
        get
        {
            if (_Context == null)
            {
                _Context = NewContext();
            }
            return _Context;
        }
    }

    private static CompanyDataContext _Context
    {
        get
        {
            return (CompanyDataContext)(HttpContext.Current != null ? HttpContext.Current.Items[HTTPCONTEXT_KEY] : _staticContext);
        }
        set
        {
            if (HttpContext.Current != null)
            {
                HttpContext.Current.Items[HTTPCONTEXT_KEY] = value;
            }
            else
            {
                DataContextManager._staticContext = value;
            }    
        }
    }

    public static void Dispose()
    {
        CompanyDataContext context = _Context;
        if (context != null)
        {
            if (Config.Instance.TestMode) context.Log.WriteLine("--- DISPOSING DATACONTEXT ---");
            context.Dispose();
            _Context = null;
        }
    }

    public static CompanyDataContext NewContext()
    {  
        CompanyDataContext db = new CompanyDataContext();
        db.CommandTimeout = Config.SQL_COMMAND_TIMEOUT;
        if (Config.Instance.TestMode)
        {
            db.Log = new ConsoleTextWriter();
            db.Log.WriteLine("--- CREATING NEW DATACONTEXT ---");
        }
        return db;
    }

}

И в Global.asax:

protected void Application_EndRequest(Object sender, EventArgs e)
{
    DataContextManager.Dispose();
}

Причина, по которой я спрашиваю, заключается в том, что мывнезапно появляются случайные исключения «SqlException: серверу не удалось возобновить транзакцию» один или два раза в день с кодом, который раньше работал идеально.После исключения мы получаем множество других исключений, пока не перезапустим веб-приложение.Кто-нибудь видел такое поведение раньше?

Мы работаем с ASP .Net 2.0 с SQL Server 2005 на IIS 6.

ОБНОВЛЕНИЕ:

Просто так никто другой не делает то же самоеужасная ошибка, которую мы совершили:

Оказалось, что некоторые рабочие потоки также использовали DataContext, но без HttpContext они, конечно, получили _staticContext (функция в DataContextManager, которая будет использоваться только при тестировании).Мы переписали код в рабочих потоках, чтобы убедиться, что один DataContext для каждого потока и утилизировать его, когда закончите.И пока все работало 2 недели:)

1 Ответ

0 голосов
/ 29 августа 2011

Это плохая картина.Во-первых, у вас никогда не должно быть статического контекста данных, который реализует IDisposable, чтобы один поток мог попытаться использовать контекст, в то время как другой избавляется от него, плюс много других потенциальных проблем.Один контекст данных на запрос http также не годится, контексты данных предназначены для использования для одной транзакции, которая затем удаляется.Вы получаете проблемы, если вы извлекаете обновление / вставку / удаление и извлекаете, используя тот же контекст, второе извлечение не отражает изменения обновления / вставки / удаления.Удалите статический контекст и просто заставьте свойство Context каждый раз возвращать новый контекст.Вы все еще можете избавиться от all в конце запроса, вставив их все в свойство List и выполнив итерацию по нему.

...