6

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

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

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 配置为忽略错误之前,是否有人知道首先阻止错误发生的方法?我缺少的新提供程序是否有一些配置?

4

3 回答 3

2

请下载更新版本的提供程序,可在此处找到:http ://www.nuget.org/packages/System.Web.Providers 。我们更新了清理过期会话以异步运行和处理错误情况的方式。如果它不能纠正您的问题,请告诉我们。

于 2012-06-25T17:29:56.440 回答
1

我在 NuGet(http://www.nuget.org/packages/System.Web.Providers) 上发布了一个关于此的问题,并得到了业主的非常快速的回复。经过一番来回后,事实证明他们确实对此进行了修复,但将在下一次更新中发布。

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

于 2012-06-28T17:13:56.787 回答
1

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

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;
    }
}

问题是一个实例在其他实例之前删除了实体,并且实体抛出了帖子中描述的错误。我要求包作者发布源代码或修复此问题。我未经测试的文本编辑器修复方法是添加公共虚拟,因此可以覆盖该方法或只是更改它。

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;
    }
}

包作者的响应速度非常快(在发布此问题时已回答!),今天他们表示他们正在努力发布代码,但他们可能能够解决这个问题。我请求了一个 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
    {
    }
}

感谢包装团队如此快速的响应和大力支持!!!

于 2013-02-04T19:19:18.443 回答