Редактирование записей базы данных несколькими пользователями

Я разработал таблицы базы данных (нормированные на сервере MS SQL) и создал автономный оконный интерфейс для приложения, которое будет использоваться несколькими пользователями для добавления и редактирования информации. Мы добавим веб-интерфейс, который позволит вам быстрее искать на нашей производственной площадке.

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

  • Не делайте ничего и надейтесь, что два пользователя никогда не будут редактировать одну и ту же запись одновременно. - Возможно, никогда не было, но что делать?
  • Процедура редактирования может хранить копию исходных данных, а также обновления, а затем сравнивать, когда пользователь закончил редактирование. Если они отличаются показами пользователей и обновлений comfirm - потребовалось бы хранить две копии данных.
  • Добавить последний обновленный столбец DATETIME и проверить его совпадение, когда мы обновляем, а затем показываем различия. - требуется новый столбец в каждой из соответствующих таблиц.
  • Создайте таблицу редактирования, которая регистрируется, когда пользователи начнут редактировать запись, которая будет проверяться, и не позволят другим пользователям редактировать одну и ту же запись. - потребует внимательного анализа потока программ для предотвращения блокировки блокировок и записей, если пользователь выйдет из программы.

Есть ли какие-нибудь лучшие решения или я должен пойти на один из них?

Ответ 2

Классический подход выглядит следующим образом:

  • добавить логическое поле, "заблокированное" для каждой таблицы.
  • установите по умолчанию значение false.
  • когда пользователь начинает редактирование, вы делаете это:

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

    • при сохранении записи установите флаг в false

Ответ 3

@Марк Харрисон: SQL Server не поддерживает этот синтаксис (SELECT ... FOR UPDATE).

эквивалентом SQL Server является подсказка оператора SELECT UPDLOCK.

Подробнее см. Электронная документация по SQL Server.

Ответ 4

Другой вариант - проверить, что значения в записи, которые вы меняете, по-прежнему такие же, как и при запуске:

SELECT 
    customer_nm,
    customer_nm AS customer_nm_orig
FROM demo_customer
WHERE customer_id = @p_customer_id

(отобразите поле customer_nm и пользователь изменит его)

UPDATE demo_customer
SET customer_nm = @p_customer_name_new
WHERE customer_id = @p_customer_id
AND customer_name = @p_customer_nm_old

IF @@ROWCOUNT = 0
    RAISERROR( 'Update failed: Data changed' );

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

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

Ответ 5

ВЫБРАТЬ ДЛЯ ОБНОВЛЕНИЯ, и эквиваленты хороши, если вы удерживаете блокировку на микроскопическое время, но для макроскопического количества (например, пользователь загружает данные и не нажал "сохранить", вы должны использовать оптимистичный concurrency как и выше. (Которое я всегда думаю, что это неправильно, это более пессимистично, чем "последний победитель писателя", который обычно рассматривается только в качестве другой альтернативы).

Ответ 6

-первое создание файла (время обновления) для хранения последней записи обновления - когда любой пользователь выбирает запись, выберите время выбора, сравните время выбора времени и времени обновления, если (время обновления) > (выберите время), что означает, что другой пользователь обновляет эту запись после выбора записи

Ответ 7

База данных сделает это за вас. Посмотрите на "select... for update", который предназначен именно для такого рода вещей. Это даст вам блокировку записи на выбранных строках, которые затем можно выполнить или отменить.

Ответ 8

Со мной лучший способ иметь столбец lastupdate (тип данных timetamp). при выборе и обновлении просто сравните это значение Еще одно продвижение этого решения состоит в том, что вы можете использовать этот столбец для отслеживания изменений времени. Я думаю, что это не хорошо, если вы просто создаете колону, такую ​​как isLock для проверки обновлений.