2010-10-15 19 views
4

我已经开始使用AspProviders代码将会话数据存储在我的表格存储中。asp.net mvc azure“访问数据存储区时出错!”

我偶尔发现了以下错误:

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 \Azure\AspProviders\TableStorageSessionStateProvider.cs:line 484 System.Web.SessionState.SessionStateModule.GetSessionStateItem() System.Web.SessionState.SessionStateModule.PollLockedSessionCallback(Object state) INNER_EXCEPTION: Microsoft.WindowsAzure.StorageClient.Tasks.Task 1.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 \Azure\AspProviders\TableStorageSessionStateProvider.cs:line 603 Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider.ReleaseItemExclusive(HttpContext context, String id, Object lockId) in \Azure\AspProviders\TableStorageSessionStateProvider.cs:line 480 INNER_EXCEPTION: System.Data.Services.Client.DataServiceContext.SaveResult.d__1e.MoveNext()

人遇到这样?我发现的唯一有用的信息是这样的,这我很犹豫吗:

If you want to bypass the validation, you can open TableStorageSessionStateProvider.cs, find ReleaseItemExclusive, and modify the code from:

svc.UpdateObject(session);

to:

svc.Detach(session);
svc.AttachTo("Sessions", session, "*");
svc.UpdateObject(session);

here

谢谢!

所以我决定改变这一点:

svc.UpdateObject(session); svc.SaveChangesWithRetries();

这样:

try { svc.UpdateObject(session);

svc.SaveChangesWithRetries(); 

} catch { svc.Detach(session); svc.AttachTo("Sessions", session, "*"); svc.UpdateObject(session);

svc.SaveChangesWithRetries(); 

}

所以,我要看看它是如何工作...

回答

9

我我也遇到过这个问题,经过一番调查后,当你有多个实例并尝试时,它似乎更经常发生在同一届会议上快速接听电话。 (例如,如果您有一个自动完成框并在每次按键时进行Ajax调用)

发生这种情况的原因是,当您尝试访问会话数据时,首先Web服务器会在该会话中取出一个锁。当请求完成时,它释放锁。使用表服务提供程序,它通过更新表中的字段来更新此锁定状态。我认为发生的事情是Instance1加载会话行,然后Instance2加载会话行,Instance1保存更新的锁定状态,并且当Instance2尝试保存锁定状态时,由于对象不处于相同状态就像它加载它时一样(ETag不再匹配)。

这就是为什么您找到的修复程序会停止发生错误的原因,因为通过在AttachTo中指定“*”,当Instance2尝试保存锁时,它将关闭ETag检查(并重写所做的更改由实例1)。

在我们的情况中,我们已经改变了提供程序,以便我们可以关闭某些路径的会话(向我们提供问题的ajax调用不需要访问会话数据,也不需要加载图像)成为你的选择取决于是什么导致你的问题。

不幸的是,TableStorageSessionStateProvider是示例项目的一部分,所以不是(据我所知,但我很乐意被告知除此之外)由Microsoft正式支持。它还有其他问题,例如一旦会话过期,它不会清除它的会话数据,所以最终会在会话表和blob容器中产生大量垃圾,您必须清理其他一些垃圾办法。

+0

真的很好回答@knightpfhor。谢谢你的帮助! – 2010-10-17 18:17:38