首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用System.Web.Providers的OptimisticConcurrencyException

使用System.Web.Providers的OptimisticConcurrencyException
EN

Stack Overflow用户
提问于 2012-03-23 23:09:45
回答 3查看 983关注 0票数 6

我正在使用微软的新Universal Providers在SQL Server中进行会话。SQL Server上的旧会话实现需要一个作业(每分钟运行一次)来清除过期的会话。新的会对每个请求进行检查和清除。因为我实际上是在SQL Azure中运行,所以我没有SQL代理来安排作业,所以这听起来是一个合理的方法(不,我不想为会话的Azure缓存付费)。

问题是,当多个用户同时访问站点时,他们都试图同时清除相同的过期会话,而第二个用户得到了乐观并发异常。

代码语言:javascript
复制
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配置为忽略错误之前,有没有人知道如何在第一时间阻止错误发生?有没有我遗漏的新提供程序的一些配置?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-02-05 03:19:18

这个包有一个我称之为bug的东西。进程外会话状态的前提是多个实例可能正在管理会话状态清理。在这种情况下,所有实例都在运行此方法...

代码语言:javascript
复制
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;
    }
}

问题是一个实例在另一个实例之前删除实体,并且实体抛出post中描述的错误。我要求软件包的作者发布源代码或修复此问题。我未经测试的文本编辑器修复方法是添加public virtual,这样就可以覆盖该方法或直接更改它。

代码语言:javascript
复制
private void PurgeExpiredSessions()
{
    using (SessionEntities entities = ModelHelper.CreateSessionEntities(this.ConnectionString))
    {   
        var sqlCommand = @"DELETE dbo.Sessions WHERE Expires < GETUTCDATE()";
        entities.ExecuteStoreCommand(sqlCommand);
        this.LastSessionPurgeTicks = DateTime.UtcNow.Ticks;
    }
}

包的作者们回复的很快(在发这篇文章的时候回答了!)今天,他们声明他们正在努力发布代码,但他们也许能够修复这个问题。我要求了一个预计到达时间,并将尝试在这里跟进,如果我得到一个。

很棒的包,只需要一点维护即可。

正确的答案:等待源代码发布或修复更新。或者自己反编译并修复它(如果这与许可证一致!)

*更新包所有者正在考虑本周修复它。耶!**Update.SOLVED!很明显,他们在不久前修复了它,而我安装了错误的软件包。我使用的是http://nuget.org/packages/System.Web.Providers,我应该使用的是http://nuget.org/packages/Microsoft.AspNet.Providers/。我不清楚哪一个是遗留的,并包含在另一个包中。他们把它装在一个空的捕获物里..

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2012-06-26 01:29:56

我们已经更新了清理过期会话以异步运行和处理错误条件的方法。

票数 2
EN

Stack Overflow用户

发布于 2012-06-29 01:13:57

我在NuGet(http://www.nuget.org/packages/System.Web.Providers)上发布了一个关于这个问题的问题,并很快得到了业主的回应。经过一些后退和前进,事实证明他们确实有解决这个问题的方法,但将在下一次更新中发布。

这里有一个建议,微软不太热衷于支持这一点,但我的经验却并非如此,并且总是得到很好的支持。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9841630

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档