Мы В нашем веб-приложении есть набор форм, которыми управляют несколько сотрудников. Формы являются общими для всех сотрудников. Прямо сейчас мы реализовали механизм блокировки. Но проблема в том, что нет надежного способа узнать, когда пользователь вышел из системы, поэтому форму необходимо разблокировать. Мне было интересно, есть ли лучший способ управлять одновременными пользователями, редактирующими одни и те же данные.
Вы можете использовать оптимистичный параллелизм, который разработан в библиотеках данных .Net. Фактически вы предполагаете, что обычно никто не будет одновременно редактировать строку. Когда это происходит, вы можете либо отказаться от сделанных изменений, либо попытаться создать более удобную логику повторения, когда у вас есть два пользователя, редактирующие одну и ту же строку.
Если вы сохраните копию того, что было в строке, когда вы начали ее редактировать, а затем запишите свое обновление как:
Update Table set column = changedvalue
where column1 = column1prev
AND column2 = column2prev...
Если это обновит нулевые строки, то вы знаете, что строка изменилась во время редактирования, и вы можете тогда обработать с ним или просто выдать ошибку и попросить пользователя повторить попытку.
Вы могли бы также создать некоторую логику повторных попыток? Перечитайте строку из базы данных и проверьте, можно ли безопасно объединить изменения, внесенные вашим пользователем, и изменения, внесенные в базу данных, а затем сделайте это автоматически. Или вы можете предоставить пользователю выбор, хотят ли они по-прежнему вносить свои изменения на основе значений, которые сейчас находятся в базе данных.
Я видел, как это делается двумя способами. Во-первых, иметь столбец «извлечено» в таблице базы данных, связанный с этими данными. Ваша служба должна искать этот флаг, чтобы увидеть, редактируется ли он. Это может истечь после достижения порога времени (с помощью триггера), если пользователь не фиксирует изменения. Второй способ - иметь выделенную "извлеченную" таблицу, в которой хранятся идентификаторы и имена объектов (возможно, имя таблицы). Это будет работать так же, и теоретически у вас будет меньше времени на поиск. Однако я вижу проблемы с параллелизмом при использовании второго метода.
Зачем нужно искать время ожидания сеанса? Просто синхронизируйте доступ к своим данным (формам или чему-то еще) и все.
ОБНОВЛЕНИЕ: Если вы имеете в виду «длинные транзакции», когда форма блокируется, как только пользователь открывает редактор (или что-то еще), и остается заблокированной до тех пор, пока пользователь не зафиксирует изменения, то:
Сделайте что-то похожее на то, что делается во многих системах контроля версий. Разрешить кому угодно редактировать данные. Когда пользователь отправляет форму, база данных проверяется на наличие изменений. Если запись не была изменена до этой отправки, разрешите ее как обычно. Если оба изменения одинаковы, игнорируйте входящее (теперь избыточное) изменение.
Если второе изменение отличается от первого, запись конфликтует. Пользователю предоставляется новая форма, в которой указано, какие поля были изменены конфликтующим обновлением. Затем пользователь несет ответственность за разрешение конфликта (путем обновления обоих наборов изменений) или за сохранение существующего обновления.
Мы ввели очень простую оптимистическую схему блокировки, которая работает следующим образом:
Это очень просто и работает достаточно хорошо.