我正在使用Microsoft的新Universal Providers进行SQL Server会话。 SQL Server上的旧会话实现需要一个作业(每分钟运行一次)来清除过期的会话。新的一个检查并清除每个请求。由于我实际上是在SQL Azure中运行,因此我没有SQL Agent来安排作业,所以这听起来像是一种合理的方式(不,我不想为会话支付Azure Cache)。 / p>
问题是当多个用户同时访问该站点时,他们都试图同时清除相同的过期会话,而第二个会获得乐观的并发异常。
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以忽略错误之前,有没有人知道一种方法来阻止错误发生在第一位?是否有一些我缺少的新提供商的配置?
答案 0 :(得分:2)
请下载较新版本的提供商,可在此处找到:http://www.nuget.org/packages/System.Web.Providers。我们更新了清理过期会话的方式,以异步方式运行并处理错误情况。如果不能解决您的问题,请告诉我们。
答案 1 :(得分:1)
我在NuGet(http://www.nuget.org/packages/System.Web.Providers)上发布了一个问题,得到了业主的快速回复。经过一些向后和向前,结果他们确实有一个解决方案,但在下一次更新中出去。
这里有一个建议,微软并不热衷于支持这一点,但我的经验却不然,并且一直得到很好的支持。
答案 2 :(得分:1)
这个包有我称之为bug的内容。进程外会话状态的前提是多个实例可能正在管理会话状态清理。在这种情况下,所有实例都运行此方法...
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,如果我拿到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
{
}
}
感谢包装团队提供快速反应和大力支持!!!