Montaż rekordy bazy danych przez wielu użytkowników

głosy
23

Mam zaprojektowane tabele bazy danych (znormalizowane, na serwerze MS SQL) i utworzony samodzielny okna front-end dla aplikacji, który będzie używany przez garstkę użytkowników, aby dodawać i edytować informacje. Dodamy interfejs WWW, aby umożliwić wyszukiwanie po drugiej stronie naszego powierzchnię produkcyjną w późniejszym terminie.

Obawiam się, że jeśli dwóch użytkowników rozpocząć edycję tego samego rekordu następnie ostatni popełnić aktualizację byłaby „zwycięzcą” i ważne informacje mogą zostać utracone. Szereg rozwiązań przyjść do głowy, ale nie jestem pewien, czy mam zamiar stworzyć większy ból głowy.

  1. Nic nie robić i mieć nadzieję, że dwaj użytkownicy nie będą edycji tego samego rekordu w tym samym czasie. - Może nigdy happed ale co jeśli nie?
  2. Montaż rutyna mogła przechowywać kopię oryginalnych danych, a także aktualizacje, a następnie porównać gdy użytkownik zakończy edycję. Jeśli różnią się one pokazać użytkownikowi i comfirm aktualizacji - wymagałoby dwie kopie danych, które należy przechowywać.
  3. Dodaj ostatniej aktualizacji kolumny DATETIME i sprawdzić pasuje kiedy aktualizować, jeśli nie to pokazać różnice. - wymaga nową kolumnę w każdym z odpowiednich tabel.
  4. Utwórz tabelę edycji, który rejestruje, gdy użytkownicy rozpocząć edycję rekordu, który zostanie sprawdzony i uniemożliwić innym użytkownikom edytowanie tego samego rekordu. - wymagałaby uważne myśl o przebiegu programu, aby uniknąć zakleszczenia i rejestry coraz zablokowana jeśli użytkownik wywala z programu.

Czy są jakieś lepsze rozwiązania czy mam iść do jednego z nich?

Utwórz 03/08/2008 o 22:23
źródło użytkownik
W innych językach...                            


8 odpowiedzi

głosy
12

Jeśli oczekujesz rzadkich kolizji, Optymistyczna współbieżność jest prawdopodobnie najlepszym.

Scott Mitchell napisał obszerny poradnik na temat wdrożenia tego wzoru:
Wdrażanie optymistycznych założeniach równoczesności

Odpowiedział 03/08/2008 o 22:31
źródło użytkownik

głosy
0

Baza danych zrobi to za Ciebie. Spójrz na „select ... for update”, który jest przeznaczony właśnie do tego rodzaju rzeczy. To daje blokadę zapisu na wybranych wierszy, które można następnie zatwierdzić lub wycofać.

Odpowiedział 04/08/2008 o 03:30
źródło użytkownik

głosy
1

@ Mark Harrison: SQL Server nie obsługuje tej składni ( SELECT ... FOR UPDATE).

Odpowiednik SQL Server jest SELECTwskazówką oświadczenie UPDLOCK.

Zobacz SQL Server Books Online , aby uzyskać więcej informacji.

Odpowiedział 04/08/2008 o 22:54
źródło użytkownik

głosy
1

Innym rozwiązaniem jest sprawdzenie, czy wartości w rejestrze, które są zmienne są wciąż takie same, jak były w momencie rozpoczęcia:

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

(Wyświetlenie pola customer_nm i użytkownik zmieni to)

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' );

Nie trzeba, aby dodać nową kolumnę do tabeli (i zachować go na bieżąco), ale trzeba stworzyć więcej komunikatów SQL i przekazać nowe i stare pola do procedury przechowywanej.

Ma też tę zaletę, że nie jesteś Blokowanie rekordów - ponieważ wszyscy wiemy, że zapisy będą kończy się pobyt zamknięty, gdy nie powinno być ...

Odpowiedział 13/08/2008 o 23:32
źródło użytkownik

głosy
1

SELECT FOR UPDATE i ich ekwiwalenty są dobre zapewniając trzymać blokadę na mikroskopijnej ilości czasu, ale dla makroskopowych ilości (np użytkownik ma dane załadowane i nie wciśnięty „zapisz” należy użyć optymistycznej współbieżności jak wyżej. (Co zawsze myślę jest misnamed - jest bardziej pesymistyczny niż "wygrywa ostatni pisarza, który jest zazwyczaj jedyną alternatywą brane pod uwagę).

Odpowiedział 01/10/2008 o 06:39
źródło użytkownik

głosy
2

Klasyczne podejście jest następujące:

  • dodać logiczną pole, „zablokowany” na każdym stole.
  • Ustawiono domyślnie na false.
  • gdy użytkownik uruchamia edycję, możesz to zrobić:

    • zablokować wiersz (lub całą tabelę, jeśli nie można zablokować wiersz)
    • sprawdź flagę na wiersz, który chcesz edytować
    • Jeśli flaga jest prawdziwe wtedy
      • informuje użytkownika, że ​​nie można edytować ten wiersz w tej chwili
    • jeszcze
      • ustawić flagę na true
    • zwolnić blokadę

    • podczas zapisywania rekordu, należy ustawić flagę z powrotem na false

Odpowiedział 01/10/2008 o 09:53
źródło użytkownik

głosy
0

Ze mną, najlepszym sposobem mam lastupdate kolumny (timetamp typ danych). po prostu wybierz i aktualizacja porównać tę wartość kolejna zaliczka tego rozwiązania jest to, że można użyć tej kolumny wyśledzić czas dane zostały zmiany. Myślę, że to nie jest dobre, jeśli tylko stworzyć Columa jak isLock dla aktualizacji wyboru.

Odpowiedział 24/06/2011 o 08:14
źródło użytkownik

głosy
1

-pierwsze tworzyć złożone (czas aktualizacji), aby zapamiętać ostatni rekord aktualizacji -Gdy każdy użytkownik rekord Oszczędzisz Wybierz czasie wybrać, porównać między wybranej dziedzinie czasu i jeśli czas aktualizacji (czas aktualizacji)> (wybierz czas) to znaczy, że kolejna aktualizacja użytkownika Ten zapis po select rekord

Odpowiedział 14/07/2016 o 11:23
źródło użytkownik

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