2016-03-14 2 views
1

У меня есть приложение C# .NET, у которого есть состояние сеанса, которое поддерживается DynamoDB. Однако я замечаю более высокую пропускную способность, которую я ожидал бы. Однако я заметил в фактической таблице, что все хранится как SessionItems в одной длинной строке.Состояние сеанса читает/записывает все, когда вы обращаетесь с DynamoDB

Но давайте говорить, что я храню несколько вещей в сеансе

Http.Context.Session["Object1"] = obj1; 
Http.Context.Session["Object2"] = obj2; 

Где obj1 и obj2 являются экземплярами двух разных классов.

Теперь, когда я иду, чтобы читать или писать один из них, например ::

var obj1 = Http.Context.Session["Object1"]; 

ли он читает все, что хранится в SessionItems на столе DynamoDB? Это одно объяснение, которое объясняет более высокую пропускную способность на столе, но кажется очень ненужным.

ответ

1

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

Однако, я думаю, что вы заметили, это ASP.NET pessimistic locking model. Когда он пытается выполнить одно чтение для извлечения данных сеанса пользователя, если данные сеанса пользователя уже установлены на нем, он будет постоянно повторять попытку для его получения (каждые 500 миллисекунд).

Специфика вашего HTTP жизненного цикл ASP.NET зависит от рамочной версии, и т.д., но общая концепция что-то вроде этого:

  1. Установить эксклюзивную блокировка на данные строки, содержащий сеанс в хранилище данных (если монопольная блокировка не может быть получены, ждать, пока это возможно)
  2. Read коллекция/Deserialize из хранилища данных строки для этой сессии
  3. Выполнить вашу страницу/контроллер
  4. Serialize/сбор записи обратно в хранилище данных
  5. Удалить исключительную блокировку

Если у вас есть несколько HTTP-запросов, обращающихся к сеансу пользователя (например, Ajax на странице) вы заметите, что нет параллелизма из-за эксклюзивных блокировок - они выполняются серийно, если для каждого из них включено Session. (даже если они явно не обращаются к Session).

Один из способов избежать этого - быть намеренным в отношении того, где вы пишете Session, а на всех других страницах/контроллерах указывается SessionStateBehavior.ReadOnly. Когда вы это сделаете, ASP.NET не установит эксклюзивную блокировку (будет использовать GetItem вместо GetItemEx). См. ASP.NET Session State Overview.

Страница:

<% @Page EnableSessionState="ReadOnly" %> 

Контроллер:

[SessionState(SessionStateBehavior.ReadOnly)] 

Ссылка:

Надеюсь, это поможет!

С уважением,

Ross

Смежные вопросы