Как вы обрабатываете несколько пользователей, редактирующих один и тот же фрагмент данных в веб-приложении?

26

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

Я пытаюсь опустить детали проекта из этого, поскольку я больше разбираюсь с общей концепцией того, как справляться со следующими ситуациями, но если это помогает, я использую Java, EclipseLink и GWT с реализованным RequestFactory. База данных PostgreSQL.

Итак, концептуальные проблемы, которые я пытаюсь решить, следующие:

  1. Если одна задача, общая для нескольких пользователей, изменяется каким-либо образом, например, задача выполнена, удалена и т. Д., Список задач всех пользователей, имеющих эту задачу, будет обновлен. Какие существуют шаблоны проектирования, которые помогают в реализации этой функции?

    • Некоторые модели, на которые я смотрел, - это Наблюдатель и Посредник - есть ли другие, которые следует рассмотреть по этим вопросам?
  2. Скажем, есть два пользователя, изменяющие одну и ту же задачу одновременно.

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

    • Во-вторых, если я не блокирую это, как мне согласовать, чьи изменения принять? Это связано с ситуацией в 1, потому что пользователь 1 может представить данные, и до того, как пользователь 2 получит обновленные данные, он / она, возможно, пошел вперед и представил свои изменения.

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

hulkmeister
источник

Ответы:

17

Я думаю, что Whiteboard будет вашим выбором для # 1, вы должны публиковать изменения в задачах (или других общих данных) в общем месте, чтобы все заинтересованные стороны могли видеть их и DTRT.

Для # 2 вам нужно взглянуть на оптимистическую блокировку . По сути, вам нужно пометить все ваши редактируемые записи временем последнего обновления. Когда вы пытаетесь сохранить запись, вы сначала проверяете, что запись в базе данных имеет ту же самую последнюю последнюю отметку времени, что и ваша запись. Если нет, то кто-то обновил запись, и теперь вам нужно либо получить обновленную запись и сообщить пользователю, что ему нужно снова внести свои изменения, либо вы можете попытаться объединить изменения пользователя в обновленную запись (что обычно получается быть простым или невозможным).

TMN
источник
7

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

Мое решение состояло в том, чтобы использовать шаблон MVC (с одной Моделью, но несколькими Контроллерами и Представлениями), где каждый Контроллер вносил изменения в Модель с использованием транзакций (используя STM ), и когда транзакция совершалась, Модель передавала уведомление об обновлении Представлениям. ).

Каждый клиент также отслеживал все, что обновлялось локально, но когда эти локальные обновления были завершены (то есть отправлены для фиксации), он возвращался к использованию информации базовой модели.

У меня также был стек отмены со всеми изменениями, внесенными пользователями, чтобы все могло быть отменено.

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

Павел
источник
4

для 1. Вы должны увидеть, подходит ли шаблон публикации / подписки .
для 2. это зависит от вашей ситуации:

  • как часто будет эта ситуация?
  • Насколько плоха ситуация, когда один из ваших пользователей не сможет обновить задачу, потому что она заблокирована или кто-то другой за это время изменил ее?
    лично я предпочитаю подход (используемый, например, в pivotaltracker ), в котором есть:
    • без замков,
    • вы видите все изменения в режиме реального времени, и
    • пользовательский интерфейс предлагает делать частые незначительные обновления вместо больших по нескольким атрибутам.
    • Вы ведете историю всех изменений, которые были сделаны. если история видна пользователям, в конечном итоге возникающие конфликты или перезаписи могут быть разрешены с помощью комментариев, аннотаций или сообщений.
kr1
источник
Вопрос носит более академический характер, поэтому я буду очень часто говорить о том, как об этом позаботятся в худшем случае. +1 за ссылки на образцы.
Халкмейстер
@ kr1 pivotaltracker не имеет предупреждения о конфликте и не объединяет несогласованные изменения, поэтому его не следует использовать как хороший пример хорошего многопользовательского приложения для редактирования записей.
Эдуардо
0
  • Блокировка записи. Это не является предпочтительным, поскольку это уменьшит параллелизм, и запись может быть заблокирована на большее время, чем необходимо.
  • Последний, чтобы отправить перезаписывает другие параллельные изменения. Пользователи не хотят этого. Некоторые программы, такие как JIRA, делают это. https://community.atlassian.com/t5/Jira-questions/Edit-a-JIRA-Issue-at-the-same-time-by-two-Users-result-in-last/qaq-p/389243
  • Параллельное редактирование. Заявка должна представлять только те поля записи, которые были изменены. Таким образом, вы предотвращаете конфликты. Большинство программ вики может объединить изменения в одно и то же текстовое поле, если нет конфликтов: /programming/3411888/how-does-a-wiki-handle-multiple-simchronous-edits См., Например, MediaWiki как это позволяет одновременное редактирование и имеет хороший пользовательский интерфейс в случае конфликтов: https://www.mediawiki.org/wiki/Extension:TwoColConflict

Я рекомендую никогда не блокировать и не сообщать о конфликте, если он случится.

Пожалуйста, посмотрите на:

https://github.com/spring-projects/spring-petclinic/issues/433

Вы можете посмотреть видео и пример кода.

Будет ли это соответствовать вашим требованиям?

Эдуардо
источник