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

голоса
23

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

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

  1. Ничего не делать и надеяться , что два пользователя никогда не будет редактировать и ту же запись одновременно. - никогда бы случалось , но что , если это делает?
  2. Редактирование рутина может хранить копию исходных данных, а также обновления , а затем сравнить , когда пользователь закончит редактирование. Если они отличаются показать пользователю и Comfirm обновление - Потребует две копии данных, подлежащих хранению.
  3. Добавить последний обновленный столбец DATETIME и проверить это соответствует при обновлении, если нет , то показать различия. - требует нового столбца в каждом из соответствующих таблиц.
  4. Создать таблицу для редактирования , который регистрирует , когда пользователи начинают редактирование записи , которые будут проверены и запретить другим пользователям редактировать же запись. - потребует carful мысли о выполнении программы для предотвращения тупиков и записи становится заблокировано , если пользователь выходит из строя из программы.

Существуют ли более эффективные решения, или я должен пойти на один из них?

Задан 03/08/2008 в 22:23
источник пользователем
На других языках...                            


8 ответов

голоса
12

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

Скотт Митчелл написал всеобъемлющий учебник по реализации этого шаблона:
Реализация оптимистической конкурентности

Ответил 03/08/2008 в 22:31
источник пользователем

голоса
2

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

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

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

    • при сохранении записи, установите флаг обратно в ложь

Ответил 01/10/2008 в 09:53
источник пользователем

голоса
1

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

Ответил 14/07/2016 в 11:23
источник пользователем

голоса
1

ВЫБРАТЬ FOR UPDATE и эквиваленты хороши предоставляя вам удерживать блокировку для микроскопического количества времени, но для макроскопического количества (например, пользователь имеет данные загружены и не нажал «сохранить», вы должны использовать оптимистический параллелизм, как описано выше. (Which Я всегда думаю, что это неверно назван - это более пессимистично, чем «последний писатель выигрывает», который, как правило, единственной альтернативой считается).

Ответил 01/10/2008 в 06:39
источник пользователем

голоса
1

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

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 и передать новые и старые поля хранимой процедуры.

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

Ответил 13/08/2008 в 23:32
источник пользователем

голоса
1

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

Эквивалент SQL Server является SELECTзаявление намек UPDLOCK.

См SQL Server Books Online для получения дополнительной информации.

Ответил 04/08/2008 в 22:54
источник пользователем

голоса
0

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

Ответил 24/06/2011 в 08:14
источник пользователем

голоса
0

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

Ответил 04/08/2008 в 03:30
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more