问题描述
我已经开始使用 AspProviders 代码将我的会话数据存储在我的表存储中.
I've started using the AspProviders code to store my session data in my table storage.
我偶尔会收到以下错误:
I'm sporadically getting the following error:
Description: Exception of type 'System.Web.HttpException' was thrown. INNER_EXCEPTION:Error accessing the data store! INNER_EXCEPTION:An error occurred while processing this request. INNER_EXCEPTION: ConditionNotMet
The condition specified using HTTP conditional header(s) is not met. RequestId:0c4239cc-41fb-42c5-98c5-7e9cc22096af Time:2010-10-15T04:28:07.0726801Z StackTrace:System.Web.SessionState.SessionStateModule.EndAcquireState(IAsyncResult ar)System.Web.HttpApplication.AsyncEventExecutionStep.OnAsyncEventCompletion(IAsyncResult ar) INNER_EXCEPTION:Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider.ReleaseItemExclusive(HttpContext context, String id, Object lockId) in AzureAspProvidersTableStorageSessionStateProvider.cs:line 484System.Web.SessionState.SessionStateModule.GetSessionStateItem()System.Web.SessionState.SessionStateModule.PollLockedSessionCallback(Object state) INNER_EXCEPTION:Microsoft.WindowsAzure.StorageClient.Tasks.Task1.get_Result()Microsoft.WindowsAzure.StorageClient.Tasks.Task
1.ExecuteAndWait()Microsoft.WindowsAzure.StorageClient.TaskImplHelper.ExecuteImplWithRetry[T](Func`2 impl, RetryPolicy policy)Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider.ReleaseItemExclusive(TableServiceContext svc, SessionRow session, Object lockId) in AzureAspProvidersTableStorageSessionStateProvider.cs:line 603Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider.ReleaseItemExclusive(HttpContext context, String id, Object lockId) in AzureAspProvidersTableStorageSessionStateProvider.cs:line 480 INNER_EXCEPTION:System.Data.Services.Client.DataServiceContext.SaveResult.d__1e.MoveNext()
有人遇到过这个吗?我发现的唯一有用的信息是这个,我很犹豫要不要这样做:
Anyone run into this? The only useful information I've found is this, which I'm hesitant to do:
如果想绕过验证,可以打开TableStorageSessionStateProvider.cs,找到ReleaseItemExclusive,修改代码从:
If you want to bypass the validation, you can open TableStorageSessionStateProvider.cs, find ReleaseItemExclusive, and modify the code from:
svc.UpdateObject(session);
svc.UpdateObject(session);
到:
svc.Detach(session);
svc.AttachTo("Sessions", session, "*");
svc.UpdateObject(会话);
svc.Detach(session);
svc.AttachTo("Sessions", session, "*");
svc.UpdateObject(session);
来自这里
谢谢!
所以我决定改变这个:
svc.UpdateObject(会话);svc.SaveChangesWithRetries();
svc.UpdateObject(session);svc.SaveChangesWithRetries();
为此:
试试{svc.UpdateObject(会话);
try{ svc.UpdateObject(session);
svc.SaveChangesWithRetries();
}抓住{svc.Detach(会话);svc.AttachTo("Sessions", session, "*");svc.UpdateObject(会话);
}catch{ svc.Detach(session); svc.AttachTo("Sessions", session, "*"); svc.UpdateObject(session);
svc.SaveChangesWithRetries();
}
所以,我会看看它是如何工作的...
So, I'll see how that works...
推荐答案
我也遇到过这个问题,经过一些调查,当你有多个实例并且你试图快速拨打电话时,它似乎更频繁地发生在同一届会议中连续.(例如,如果您有一个自动完成框并在每次按键时进行 ajax 调用)
I've encountered this problem as well and after some investigation it seems to happen more often when you have more than one instance and you try to make calls in rapid succession in the same session. (e.g. if you had an auto complete box and making ajax calls on each key press)
发生这种情况是因为当您尝试访问会话数据时,首先网络服务器会锁定该会话.当请求完成时,它释放锁.对于表服务提供者,它通过更新表中的字段来更新此锁定状态.我认为发生的事情是 Instance1 加载会话行,然后 Instance2 加载会话行,Instance1 保存更新的锁定状态,当 Instance2 尝试保存锁定状态时,它会出错,因为对象不在同一状态就像它加载时一样(ETag 不再匹配).
This occurs because when you try to access the session data, first of all the web server takes out a lock on that session. When the request is complete, it releases the lock. With the table service provider, it updates this lock status by updating a field in the table. What I think is happening is that Instance1 loads the session row, then Instance2 loads the session row, Instance1 saves down the updated lock status and when Instance2 attempts to save the lock status it gets an error because the object isn't in the same state as when it loaded it (the ETag doesn't match any more).
这就是为什么您找到的修复将阻止错误发生的原因,因为通过在 AttachTo 中指定*",当 Instance2 尝试保存锁定时,它将关闭 ETag 检查(并覆盖由实例1).
This is why the fix that you found will stop the error from occurring, because by specifying the "*" in the AttachTo, when Instance2 attempts to save the lock it will turn off ETag checking (and over write the changes made by Instance1).
在我们的情况下,我们更改了提供程序,以便我们可以关闭某些路径的会话(给我们带来问题的 ajax 调用不需要访问会话数据,也不需要访问会话数据),这可能是根据导致问题的原因为您提供一个选项.
In our situation we have altered the provider so that we can turn off session for certain paths (the ajax call that was giving us our problems didn't need access to session data, neither did the loading of images) which may be an option for you depending on what is causing your problem.
不幸的是,TableStorageSessionStateProvider 是示例项目的一部分,因此(据我所知,但我很高兴被告知其他情况)并未得到 Microsoft 的正式支持.它确实有其他问题,例如一旦会话到期它就不会清理它的会话数据,因此您最终会在会话表和 blob 容器中出现大量垃圾,您必须清理其他一些方式.
Unfortunately the TableStorageSessionStateProvider is part of the sample projects and so isn't (as far as I'm aware, but I'll happily be told otherwise) officially supported by Microsoft. It does have other issues, like the fact that it doesn't clean up it's session data once a session expires, so you will end up with lots of junk in the session table and blob container that you'll have to clean up some other way.
这篇关于asp.net mvc azure“访问数据存储时出错!"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!