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

Я вы столкнулись с этой проблемой, и после некоторого расследования это, как представляется, происходит чаще, когда у вас более одного экземпляра и y ou попытайтесь совершать вызовы в быстрой последовательности на той же сессии. (например, если у вас есть автозаполнение и совершение аякс-вызовов при каждом нажатии клавиши)

Это происходит потому, что, когда вы пытаетесь получить доступ к данным сеанса, в первую очередь веб-сервер вынимает блокировку на этом сеансе. Когда запрос будет завершен, он освободит блокировку. С поставщиком услуг таблицы он обновляет этот статус блокировки, обновляя поле в таблице. Я считаю, что экземпляр 1 загружает строку сеанса, а Instance2 загружает строку сеанса, экземпляр 1 сохраняет обновленный статус блокировки и когда экземпляр2 пытается сохранить статус блокировки, он получает ошибку, потому что объект не находится в том же состоянии как при его загрузке (ETag больше не соответствует).

Вот почему исправление, которое вы нашли, остановит ошибку, потому что, указав «*» в AttachTo, когда Instance2 попытается сохранить блокировку, он отключит проверку ETag (и надпишет сделанные изменения по экземпляру 1).

В нашей ситуации мы изменили поставщика, чтобы мы могли отключить сеанс для определенных путей (вызов ajax, который давал нам наши проблемы, не нуждался в доступе к данным сеанса, а также загрузке изображений), которые могут быть вариантом для вас в зависимости от того, что вызывает вашу проблему.

К сожалению, TableStorageSessionStateProvider является частью типовых проектов, и это не так (насколько мне известно, но я с радостью расскажу об этом), официально поддерживаемом Microsoft. У него есть другие проблемы, например, тот факт, что он не очищает данные сеанса после истечения срока действия сеанса, поэтому у вас будет много мусора в таблице сеансов и контейнере blob, что вам придется очистить некоторые другие путь.

+0

действительно хороший ответ @knightpfhor. Спасибо за вашу помощь! –