2010-10-15 41 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