asp.net mvc azure "Ошибка доступа к хранилищу данных!" - PullRequest
4 голосов
/ 15 октября 2010

Я начал использовать код AspProviders для хранения моих данных сеанса в хранилище таблиц.

Я периодически получаю следующую ошибку:

Описание: было сгенерировано исключение типа System.Web.HttpException.INNER_EXCEPTION: Ошибка доступа к хранилищу данных!INNER_EXCEPTION: при обработке этого запроса произошла ошибка.INNER_EXCEPTION: ConditionNotMet Условие, указанное с помощью условных заголовков HTTP, не выполнено.RequestId: 0c4239cc-41fb-42c5-98c5-7e9cc22096af Время: 2010-10-15T04: 28: 07.0726801Z StackTrace: System.Web.SessionState.SessionStateModule.EndAcquireState (IAsyncResult ar) System.Web.HynSyncEnsynE) INNER_EXCEPTION: Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider.ReleaseItemExclusive (HttpContext контекст, идентификатор строки, объект lockId) в \ Azure \ AspProviders \ TableStorageSessionStateProvider.cs: строка 484 System.Web.SessionState.SessionStateModule.GetSessionStateItem () System.Web.SessionState.SessionStateModule.PollLockedSessionCallback (состояние объекта) INNER_EXCEPTION: Microsoft.WindowsAzure.StorageClient.Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider.ReleaseItemExclusive (TableServiceContext svc, сеанс SessionRow, объект lockId) в\ Azure \ AspProviders \ TableStorageSessionStateProvider.cs: строка 603 Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider.ReleaseItemExclusive (HttpContext контекст, идентификатор строки, объект lockId) в \ Azure \ AspProviders \ TableStorageSessionStateProvider.cs: строка 480 INNER_EXCEPTION: System.Data.Services.Client.DataServiceContext.SaveResult.d__1e.MoveNext ()

Кто-нибудь сталкивался с этим?Единственная полезная информация, которую я нашел, это то, что я не решаюсь сделать:

Если вы хотите обойти проверку, вы можете открыть TableStorageSessionStateProvider.cs, найтиReleaseItemExclusive и измените код с:

svc.UpdateObject (сеанс);

на:

svc.Detach (сеанс);
svc.AttachTo ("Сессии ", сессия," * ");
svc.UpdateObject (сессия);

с здесь

Спасибо!

Поэтому я решил изменить это:

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

к этому:

try {svc.UpdateObject (session);

svc.SaveChangesWithRetries();

} catch {svc.Detach (session);svc.AttachTo ("Сеансы", сессия, "*");svc.UpdateObject (session);

svc.SaveChangesWithRetries();

}

Итак, я посмотрю, как это работает ...

1 Ответ

9 голосов
/ 17 октября 2010

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...