OptimisticConcurrencyException с System.Web.Providers - PullRequest
6 голосов
/ 23 марта 2012

Я использую новые Универсальные провайдеры от Microsoft для сеанса в SQL Server. В старой реализации сеанса на SQL Server требовалось задание (выполняемое каждую минуту) для очистки истекших сеансов. Новый проверяет и очищает каждый запрос. Поскольку я на самом деле работаю в SQL Azure, у меня нет агента SQL для планирования заданий, так что это разумный способ сделать это (нет, я не хочу платить за Azure Cache за сеанс).

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

System.Data.OptimisticConcurrencyException: Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.
   at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter)
   at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)
   at System.Web.Providers.DefaultSessionStateProvider.PurgeExpiredSessions()
   at System.Web.Providers.DefaultSessionStateProvider.PurgeIfNeeded()
   at System.Web.SessionState.SessionStateModule.BeginAcquireState(Object source, EventArgs e, AsyncCallback cb, Object extraData)
   at System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Я использую ELMAH для регистрации ошибок, и это проявляется с некоторой частотой. Прежде чем я попытаюсь настроить ELMAH для игнорирования ошибок, кто-нибудь знает, как вообще предотвратить появление ошибок? Есть ли какая-то конфигурация с новыми провайдерами, которые мне не хватает?

Ответы [ 3 ]

2 голосов
/ 25 июня 2012

Пожалуйста, загрузите более новую версию провайдеров, которую можно найти здесь: http://www.nuget.org/packages/System.Web.Providers. Мы обновили способ очистки сеансов с истекшим сроком для асинхронной работы и обработки ошибок.Пожалуйста, дайте нам знать, если это не исправит ваши проблемы.

1 голос
/ 04 февраля 2013

Этот пакет содержит то, что я бы назвал ошибкой.Предпосылка состояния сеанса вне процесса состоит в том, что несколько экземпляров могут управлять очисткой состояния сеанса.В этом случае все экземпляры запускают этот метод ...

private void PurgeExpiredSessions()
{
    using (SessionEntities entities = ModelHelper.CreateSessionEntities(this.ConnectionString))
    {
        foreach (SessionEntity entity in QueryHelper.GetExpiredSessions(entities))
        {
            entities.DeleteObject(entity);
        }
        entities.SaveChanges();
        this.LastSessionPurgeTicks = DateTime.UtcNow.Ticks;
    }
}

Проблема состоит в том, что один экземпляр удаляет объекты до того, как другой (и) и объекты выдают ошибку, описанную в посте.Я попросил авторов пакета выпустить исходный код или исправить это .. Мое непроверенное исправление текстового редактора состояло в том, чтобы добавить общедоступную виртуальную систему, чтобы можно было переопределить метод или просто изменить его тоже.Авторы пакетов действительно быстро получают ответ (ответив при публикации!), и сегодня они заявили, что работают над выпуском кода, но могут исправить это.Я запросил ETA и постараюсь проследить за этим, если я его получу.

Отличный пакет, просто нужно немного поработать.

Правильный ответ: дождитесь выпуска исходного кода или обновления исправления.Или декомпилируйте и исправьте его самостоятельно (если это согласуется с лицензией!)

* Обновление владельцев пакетов рассматривает возможность исправления на этой неделе.Да уж!** Update.SOLVED !!!Очевидно, они исправили это некоторое время назад, и я устанавливал неправильный пакет .. Я использовал http://nuget.org/packages/System.Web.Providers, и я должен был использовать http://nuget.org/packages/Microsoft.AspNet.Providers/ .. Мне не было очевидно, какой из них был устаревшим ивходит в другой пакет.Они завернули его в пустую ловушку ..

private void PurgeExpiredSessions()
{
    try
    {
        using (SessionEntities entities = ModelHelper.CreateSessionEntities(this.ConnectionString))
        {
            foreach (SessionEntity entity in QueryHelper.GetExpiredSessions(entities))
            {
                entities.DeleteObject(entity);
            }
            entities.SaveChanges();
            this.LastSessionPurgeTicks = DateTime.UtcNow.Ticks;
        }
    }
    catch
    {
    }
}

Спасибо команде разработчиков за такие быстрые ответы и отличную поддержку !!!

1 голос
/ 28 июня 2012

Я отправил вопрос по этому вопросу в NuGet (http://www.nuget.org/packages/System.Web.Providers), и получил очень быстрый ответ от владельцев. После небольшого переворота, оказывается, у них есть исправление для этого, но он выходит в следующее обновление.

Было высказано предположение, что Microsoft не слишком заинтересована в поддержке этого, но мой опыт был иным, и всегда получал хорошую поддержку.

...