Как мне реализовать “пессимистическую блокировку” в приложении asp.net?

StackOverflow https://stackoverflow.com/questions/617934

  •  03-07-2019
  •  | 
  •  

Вопрос

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

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

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

  • Какие данные я должен приложить к записи заказа?Я обдумываю:
    • Заблокированный
    • Время получения блокировки
    • Время обновления блокировки

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

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

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

Это было полезно?

Решение

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

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

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

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

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

Другие советы

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

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

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

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 года назад по специальному заказу клиента.После этого клиента никто больше не просил меня сделать что-либо подобное, так что я не добился никакого другого метода.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top