Как реализовать «пессимистическую блокировку» в приложении asp.net? - PullRequest
6 голосов
/ 06 марта 2009

Я хотел бы получить совет от любого, кто имел опыт реализации чего-то вроде «пессимистической блокировки» в приложении asp.net. Это поведение, которое я ищу:

  1. Пользователь А открывает ордер # 313
  2. Пользователь B пытается открыть ордер # 313, но ему сообщают, что для пользователя A ордер был открыт исключительно в течение X минут.

Поскольку я не реализовывал эту функциональность раньше, у меня есть несколько вопросов о дизайне:

  • Какие данные я должен прикрепить к записи заказа? Я считаю:
    • LockOwnedBy
    • LockAcquiredTime
    • LockRefreshedTime

Я бы посчитал запись разблокированной, если LockRefreshedTime <(сейчас - 10 минут). </p>

  • Как я могу гарантировать, что блокировки не будут удерживаться дольше, чем необходимо, но также не истекают неожиданно?

Мне вполне комфортно с jQuery, поэтому приветствуются подходы, в которых используется клиентский скрипт. Это будет внутреннее веб-приложение, поэтому я могу быть довольно либеральным с моим использованием пропускной способности / циклов. Мне также интересно, является ли термин "пессимистическая блокировка" подходящим для этой концепции.

Ответы [ 2 ]

8 голосов
/ 06 марта 2009

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

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

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

Относительно того, как вы убедитесь, что блокировки не открываются неожиданно. Убедитесь, что если у вас есть какой-нибудь длительный процесс, который может работать дольше, чем время ожидания блокировки, он обновляет свою блокировку во время выполнения.

Термин «явная блокировка» также используется для описания этого времени блокировки.

1 голос
/ 21 июля 2011

Я сделал это вручную.

  • Сохранить первичный ключ записи в таблице блокировок и пометить запись Атрибут режима для редактирования.
  • Когда другой пользователь пытается выбрать эту запись, укажите пользователя запись только готов.
  • Установите максимальное время для блокировки записей.
  • Обновить данные страницы для заблокированных записей. Пока пользователю разрешено вносить изменения, все остальные пользователи могут только проверять.

Таблица блокировки должна иметь дизайн, подобный следующему:

User_ID, //who locked
Lock_start_Time,
Locked_Row_ID(Entity_ID), //this is primary key of the table of locked row.
Table_Name(Entity_Name) //table name of the locked row.

Остальная логика - это то, что вы должны выяснить.

Это просто идея, которую я реализовал 4 года назад по специальному запросу клиента. После этого клиента никто больше не просил меня сделать что-то подобное, поэтому я не нашел другого метода.

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