Когда несколько пользователей одновременно редактируют один и тот же элемент приложения, во время сохранения может возникнуть конфликт. Это приведёт к тому, что изменения не сохранятся, данные потеряются, и в системе будет отображаться неактуальная информация.
Для решения этой проблемы реализовано:
- Атомарное изменение атрибутов — сохраняются только отредактированные поля, а не весь элемент целиком.
- Контроль конфликтов и блокировка записи изменений — при наличии конфликта пользователь получает уведомление о необходимости обновить страницу перед повторным сохранением, кнопка сохранения временно становится неактивной.
- Проверка версий элемента на сервере — элемент содержит уникальный идентификатор версии
__version
, который обновляется при каждом сохранении данных.
Когда пользователь открывает карточку элемента, с сервера загружается текущее значение атрибута. После того как пользователь завершил редактирование и сохранил элемент, на сервере происходит проверка версий:
- если версии совпадают во всём, кроме внесённых пользователем изменений, то версия на сервере обновляется;
- если версии не совпадают, значит элемент был изменён параллельно. Корректировки пользователя отклоняются с ошибкой «version inconsistency: collision», он увидит уведомление о конфликте с просьбой обновить страницу. Кнопка сохранения блокируется;
- если пользователь изменил значение полей, но затем вернул прежние данные и сохранил элемент, то на сервер возвращается версия без фактических изменений, значение атрибута остаётся текущим.
Механизм обработки конфликтов при сохранении применяется:
- когда пользователи вручную открывают элемент на редактирование;
- при изменении элемента в рамках бизнес-процесса, исполнения скрипта или методов Web API.
Чтобы активировать защиту от конфликтов, в настройках приложения включите опцию Предотвращать конфликты сохранений.
Начало примера
Обратите внимание на следующие ограничения:
- предотвращение конфликтов доступно только для пользовательских свойств приложения. При изменении системных полей, например статуса, уведомление не отправляется;
- в системе прав доступа и при удалении элемента отслеживание изменений не поддерживается;
- одновременное редактирование данных в рамках массовых действий не обрабатывается.
Конец примера
Примеры предотвращения конфликтов при сохранении элемента
Кейс 1. Пользователи одновременно редактируют элемент
- Пользователь А открывает карточку клиента и редактирует поле Номер телефона.
- В это время пользователь Б открывает ту же карточку и редактирует поле Email.
- Пользователь А сохраняет свои изменения.
- В результате пользователь Б получает уведомление «Элемент изменен! Чтобы избежать потери данных, обновите страницу, прежде чем продолжить». Кнопка Сохранить временно блокируется.
Пользователь Б обновляет карточку и видит актуальный номер телефона, введённый пользователем А. Он может повторно ввести и сохранить новый email.
Кейс 2. Элемент редактируется одновременно вручную и в рамках задачи бизнес-процесса
- В системе настроен бизнес-процесс, в рамках которого пользователю А приходит задача на изменение данных элемента. Он редактирует поле Email.
- Параллельно пользователь Б открывает карточку того же элемента, редактирует поле Телефон и сохраняет изменения.
- Пользователь А получает уведомление «Элемент изменен! Чтобы избежать потери данных, обновите страницу, прежде чем продолжить». Кнопка Сохранить временно блокируется.
Пользователь А обновляет карточку задачи, видит актуальный номер, введённый пользователем Б. Он повторно вводит и сохраняет новый email.
Кейс 3. Элемент редактируется одновременно вручную и в рамках исполнения скрипта в бизнес-процессе
- Пользователь А открывает карточку клиента и редактирует поле Email.
- Параллельно пользователь Б запускает бизнес-процесс, в рамках которого выполняется скрипт для автоматического изменения электронной почты того же клиента.
- Пользователь А сохраняет изменения.
- Если экземпляр процесса ещё не выполнился, он завершится с ошибкой «version inconsistency: collision». На сервере сохранятся данные, введённые пользователем А.
Если пользователь А сохранил свои изменения после отработки скрипта, то он получит уведомление «Элемент изменен! Чтобы избежать потери данных, обновите страницу, прежде чем продолжить». Кнопка Сохранить временно заблокируется.
Пользователь А обновляет карточку, видит актуальные данные и может повторно ввести и сохранить email.
Важно: в этом кейсе для корректной работы блока Скрипт в его настройках на вкладке Обработка ошибок:
- отключите опцию Повторить выполнение, чтобы избежать бесконечных попыток перезаписи данных;
- включите опцию Оповещение и выберите получателя уведомления об ошибке. Администратор сможет решить её в мониторе ошибок и, например, перезапустить процесс.
Кейс 4. Элемент изменяется одновременно вручную и в рамках выполнения методов Web API
- Пользователь А открывает карточку клиента и редактирует поле Номер телефона.
- В это же время от внешней системы или другого пользователя через Web API отправляется запрос на обновление этого же поля в той же карточке.
- Пользователь А сохраняет изменения.
- Если запрос от Web API ещё не завершился, в ответ вернётся ошибка «version inconsistency: collision». На сервере сохранятся данные, введённые пользователем А.
Если пользователь А сохранил свои изменения после выполнения запроса, то ему придёт уведомление «Элемент изменен! Чтобы избежать потери данных, обновите страницу, прежде чем продолжить», кнопка Сохранить временно заблокируется.
Пользователь А обновит карточку, увидит актуальные данные и сможет повторно ввести и сохранить номер.
Кейс 5. Элемент одновременно редактируется вручную и в рамках исполнения скрипта в виджете
- Пользователь А открывает карточку клиента и редактирует поле Номер телефона.
- Параллельно пользователь Б в той же карточке нажимает кнопку, которая запускает скрипт для автоматического изменения номера клиента.
- Пользователь А сохраняет изменения.
- Если скрипт ещё не выполнился, вернётся ошибка «version inconsistency: collision». На сервере сохранятся данные, введённые пользователем А.
Если пользователь А сохранил свои изменения после исполнения скрипта, то ему придёт уведомление «Элемент изменен! Чтобы избежать потери данных, обновите страницу, прежде чем продолжить», кнопка Сохранить временно заблокируется.
Пользователь А обновит карточку, увидит актуальные данные и сможет повторно ввести и сохранить номер.
Обработка ошибок в скриптах с помощью try – catch
Чтобы при конфликте сохранений скрипты не завершались ошибкой, вы можете использовать конструкцию для обработки ошибок try – catch
.
Рассмотрим кейс:
- Пользователь А открывает карточку клиента и редактирует поле Номер телефона.
- Параллельно пользователь Б запускает бизнес-процесс со скриптом, в рамках исполнения которого получает задачу на изменение этого же элемента и вводит новый номер.
- Пользователь А сохраняет изменения.
- Если скрипт ещё не завершился, вернётся ошибка «version inconsistency: collision». Сработает
try – catch
, ошибка автоматически обработается и скрипт продолжит выполняться. На сервере сохранятся данные, введённые пользователем Б, а пользователь А получит уведомление о конфликте.