我正在使用微软的新Universal Providers在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配置为忽略错误之前,有没有人知道如何在第一时间阻止错误发生?有没有我遗漏的新提供程序的一些配置?
发布于 2013-02-05 03:19:18
这个包有一个我称之为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;
}
}问题是一个实例在另一个实例之前删除实体,并且实体抛出post中描述的错误。我要求软件包的作者发布源代码或修复此问题。我未经测试的文本编辑器修复方法是添加public virtual,这样就可以覆盖该方法或直接更改它。
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/。我不清楚哪一个是遗留的,并包含在另一个包中。他们把它装在一个空的捕获物里..
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
{
}
}感谢包团队如此快速的响应和大力的支持!
发布于 2012-06-26 01:29:56
我们已经更新了清理过期会话以异步运行和处理错误条件的方法。
发布于 2012-06-29 01:13:57
我在NuGet(http://www.nuget.org/packages/System.Web.Providers)上发布了一个关于这个问题的问题,并很快得到了业主的回应。经过一些后退和前进,事实证明他们确实有解决这个问题的方法,但将在下一次更新中发布。
这里有一个建议,微软不太热衷于支持这一点,但我的经验却并非如此,并且总是得到很好的支持。
https://stackoverflow.com/questions/9841630
复制相似问题