Параллелизм: только один пользователь редактирует элемент одновременно - PullRequest
4 голосов
/ 21 января 2012

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

Вот проблема:

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

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

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

Я реализовал это, установив флаг для элемента inUse в значение true, а затем проверил это.Когда пользователь завершит редактирование элемента, нажав кнопку «Сохранить» или «Отмена», для флага будет установлено значение false.Проблема этого подхода заключается в учете случаев, когда пользователь оставляет свой браузер открытым или браузер закрыт.

Я попытался установить тайм-аут сеанса, но не могу заставить его работать, потому что по истечении времени сеанса у меня нет доступа к этому элементу.У меня есть доступ только к идентификатору сеанса httprequest.

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

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

Я нашел это решение Разрешен только один пользовательредактировать контент за один раз , но не уверен, так ли это на Java.

Есть ли более элегантное решение / Java?Если да, можете ли вы указать мне правильное направление, пожалуйста?Как бы вы это реализовали?

Спасибо!

Решение: Хотя изначально я думал, что оптимистичная блокировка - это путь, я быстро понял, что она действительно не будет работать для моей среды.Я решил использовать комбинацию пессимистической блокировки (http://www.agiledata.org/essays/concurrencyControl.html#PessimisticLocking) и тайм-аутов.

Когда к элементу обращаются, я устанавливаю для поля inUse значение true, а для последнего доступного поля объекта - текущее время.

Каждый раз, когда кто-то пытается отредактировать объект, я проверяю поле inUse и поле lastAccessed + 5 минут, поэтому в основном я даю 5 минут на редактирование пользователя.

Ответы [ 4 ]

3 голосов
/ 21 января 2012

Делайте это так, как они делают в базе данных, где используется метка времени. Временная метка сохраняется вместе с записью, и когда человек отправляет свое редактирование, редактирование не проходит, если только временная метка не совпадает (то есть «никаких изменений не произошло, так как я прочитал эту запись»). Затем, когда редактирование проходит, создается новая отметка времени.

0 голосов
/ 22 января 2012

Мартин Фаулер описывает 4 шаблона для такой проблемы:

  1. Онлайн-оптимистическая блокировка
  2. Онлайн-пессимистическая блокировка
  3. Автономная оптимистическая блокировка
  4. ОфлайнПессимистическая блокировка

Вы должны решить, какую из них использовать в соответствии с вашей проблемой.JPA, JDO и Hibernate предоставляют 1 и 2 из коробки.Hibernate также может обрабатывать 3 (я не уверен насчет JPA и JDO).Ни один из ручек 4 из коробки, и вы должны реализовать это самостоятельно.

0 голосов
/ 21 января 2012

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

На уровне пользовательского интерфейса, чтобы обработать ваш сценарий использования, я бы сделал лизинг ресурсов :

  1. Добавьте два поля в таблицу:

    • LAST_LEASE_TIME: время последней аренды
    • LAST_LEASE_USER: пользователь, который арендовал запись в последний раз.
  2. Когда пользователь пытается отредактировать вашу запись, сначала убедитесь, что запись не сдана в аренду или срок аренды истек (то есть срок аренды не превышает указанное время аренды) или что пользователь тот, который был предоставлен в аренду.

  3. Периодически обновляйте аренду через веб-браузер, например, с помощью вызова AJAX.

  4. Когда пользователь заканчивает редактирование записи, явно истекает срок аренды.

Используя лизинг, вы решаете проблему «закрытого браузера»: после истечения срока аренды без обновления аренды алгоритм автоматически «освобождает» ресурс.

0 голосов
/ 21 января 2012

Похоже, вы могли бы использовать: Session Beans Цитата:

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

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

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