оптимистичный параллелизм с отметкой времени и набором данных в asp.net - PullRequest
3 голосов
/ 14 сентября 2011

Я создаю систему форумов для моего веб-сайта с использованием c # и asp.net, а для доступа к данным я использую набор типизированных данных, а для пользовательского интерфейса - шаблон mvp.В моей базе данных я сохранил процедуры, которые были добавлены в мой набор данных.проблема заключалась в том, что набор данных не позволил мне установить флажок «использовать оптимистичный параллелизм», поэтому мне пришлось самому реализовать оптимистический параллелизм.мне добавили столбец метки времени в мои таблицы, теперь у меня проблема с сохранением этого значения для каждого пользователя!так какой подход к управлению состоянием безопасен и менее затратен для сохранения значения метки времени?

Я подумал, что может быть лучше использовать сеанс для хранения значения, но если число пользователей возрастет, у меня возникнет проблемаоднако, используя ресурсы памяти, я могу настроить сеанс на использование сервера sql вместо памяти, но я понятия не имею, насколько медленнее это будет, поэтому я не могу определиться с этим.*

Редактировать1: Да.Я хочу отслеживать последнюю модификацию строки, чтобы увидеть, совпадает ли она с той, что есть у пользователя.но я не знаю, где сохранить значение временной метки пользователя.

1 Ответ

6 голосов
/ 14 сентября 2011

Если по какой-то причине вы не можете использовать метку времени / строку, поскольку это приложение типа форума, я думаю, вы отслеживаете созданную / измененную дату / время поста?Если это так, это было бы легко проверить.

ОБНОВЛЕНО

Режим SQL Server

Вариант использования режима SQL Server обычно представляет собой ферму веб-серверов, поэтому состояние сеанса ASP.NET сохраняется на нескольких серверах.Это делает его немного более надежным, поскольку если веб-сервер становится недоступным, пока доступен другой, сеанс может продолжаться в обычном режиме.Режим SQL Server работает не так быстро, как локально, если только ресурсы не подвергаются серьезной конкуренции, потому что мы запрашиваем базу данных вместо того, чтобы выполнять оперативную память на том же сервере (вне процесса) или даже в том же процессе (внутри процесса).

Шаблон MVC и состояние сеанса

Если вы используете WebFormViewEngine в своем приложении, вы можете использовать состояние, однако основной арендатор шаблона MVC должен бытьбез состояния.

Как отследить изменение строки / временную отметку без сохранения состояния

Чтобы отследить изменение строки без сохранения состояния, нам нужно вернуть его клиенту таккогда выполняется обратный вызов действия контроллера, он предоставляется нам.

<%= Html.HiddenFor(Model.VersionId) %>

, что приведет к появлению скрытого поля в итоговой HTML-форме.

<input type="hidden" name="VersionId">1</input> 

Это безопасно?

Безопасно ли временно хранить это на клиенте, прекрасно понимая, что, возможно, кто-то может изменить значение в рамках атаки на ваше веб-приложение.

Давайте проанализируем то, что мы знаем:

  • Microsoft не рекомендует увеличивать его вручную, чтобы предотвратить дублирование одной и той же версии строки в той же таблице.
  • Увеличиваетсяпоследовательно для каждой вставки / обновления таблицы, а не для каждой записи.т.е. запись A может иметь версию 1, запись B может иметь версию 2. При следующем обновлении записи A это будет 3, а не 2. См. http://msdn.microsoft.com/en-us/library/ms182776.aspx.

На основании этого мы напишем наше приложение для использованияrowversion, чтобы мы использовали rowversion, чтобы определить, изменилась ли запись между обновлениями для нашего текущего запроса.Мы всегда будем позволять БД внутренне увеличивать версию строки.Таким образом, процедура сохранения примет значение для сравнения, но не будет вставлять или обновлять его в таблице / представлении.

Так, каковы случаи, которые могут произойти с преобразованием строк, если кто-то попытается манипулировать им.

  1. Предоставленная клиентом версия строки меньше, чем версия строки БД.
  2. Предоставленная клиентом версия строки равна версии строки БД.
  3. Предоставленная клиентом версия строки больше, чемверсия строки в БД.

Давайте теперь разберем это.

Так что, если версия клиента меньше БД, что это значит?

Клиент использовал старую копию данных при редактировании, поскольку они изменились с момента последнего чтения из БД.Чтобы справиться с этим, мы можем:

A.Дайте им ошибку, перезагрузите данные и попросите их повторно отправить изменения.

B.Объедините их изменения с текущей копией и запросите подтверждение перед повторной отправкой.

C.Переопределить существующую копию в БД.Что ж, мы могли бы сделать это, но, поскольку мы реализовали модель параллелизма для обработки нескольких изменений одновременно, это может быть не лучшим вариантом.Это оставляет нас с A и B.

Другой вариант - клиент изменил значение rowversion, чтобы оно было меньше, чем фактическое значение DB.В этом случае, даже если они изменили значение rowversion, имеет ли это значение?Я бы предположил, что это не так, и он должен обрабатываться так же, как если бы произошли изменения одновременно с другим пользователем.Снова вернем опции A и B.

Так что, если версия клиента равна БД, что это значит?

Клиент редактирует ожидаемую версию инажмите кнопку отправки.Чтобы справиться с этим, мы можем:

A.Примите их изменения и продолжайте.

B.Запретить изменения и предоставить сообщение обратной связи.Маловероятно, что мы хотим сделать это, поскольку весь смысл состоит в том, чтобы получить данные в базу данных.

Другой вариант заключается в том, что клиент изменил значение rowversion, чтобы оно было именно той версией, которую мы ожидали,или, по всей вероятности, не изменили его вообще, потому что мы сказали им, какую версию строк мы ожидали, как и для всех представлений.Но в случае, если они изменили версию строки, и были одновременные клиенты, которые разместили свои обновления, и это последнее обновление, которое должно быть отправлено.

Мы можем обработать этот случай так же, как и до A или B. К сожалению, мыне знаю, что они действительно изменили версию строки, потому что это было так, как ожидалось.Однако мы уже дали им разрешение на обновление записи.Если они не должны обновлять запись, у них не должно быть разрешения на это.

Тем не менее, мы по-прежнему будем проверять все входные данные для исправности и очищать их перед записью в БД.

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

Так что, если клиентская версия строки больше, чем БД, что это значит?

Что ж, параметры точно такие же, как если бы версия строки была меньше БД.Это не ожидалось, поэтому либо А, либо Б. Снова, вероятно, вариант С не является вариантом, поскольку он побеждает цель.

Заключение

Итакэто безопасно для веб-приложения форума?Нам по-прежнему нужно проверять ввод, но если версия строки отличается от ожидаемой, у нас есть методы для ее решения.

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

Так что, на мой взгляд, да, но это в конечном итоге ваш призыв.

...