Czy powinienem blokować wiersze w mojej bazie danych w chmurze podczas ich edycji przez użytkownika?

12

Tworzę aplikację komputerową, która utrwala dane w chmurze. Jedną z moich obaw jest rozpoczęcie edycji elementu w aplikacji i pozostawienie go na jakiś czas, powodując, że dane staną się nieaktualne. Może się to oczywiście zdarzyć również wtedy, gdy 2 osoby będą jednocześnie edytować ten sam element. Kiedy kończą edycję i chcą zapisać dane, musiałbym albo zastąpić to, co obecnie istnieje w bazie danych, albo sprawdzić, czy rozpoczęli edycję po ostatniej zmianie i zmusić ich do odrzucenia zmian lub dać im możliwość zaryzykowania nadpisywanie cudzych zmian.

Myślałem o dodaniu pól is_lockedi lock_timestampdo tabeli DB. Gdy użytkownik rozpocznie edycję elementu, wiersz zmieni się is_lockedna true i ustawi znacznik czasu blokady na bieżący czas. Miałbym wtedy trochę czasu na blokadę (np. 5 minut). Jeśli ktokolwiek spróbuje edytować element, otrzyma komunikat z informacją, że element jest zablokowany i kiedy blokada wygasa automatycznie. Jeśli użytkownik odejdzie podczas edycji, blokada automatycznie wygaśnie po stosunkowo krótkim czasie, a gdy to zrobi, zostanie ostrzeżony, że blokada wygasła i będzie zmuszony do ponownego uruchomienia edycji po odświeżeniu danych.

Czy byłaby to dobra metoda zapobiegania nadpisywaniu nieaktualnych danych? Czy to przesada (nie oczekuję, że aplikacja będzie używana przez więcej niż kilka osób jednocześnie na jednym koncie).

(Innym problemem, który mam, jest to, że 2 osoby dostają blokadę na ten sam przedmiot, jednak uważam, że jest to stan wyścigowy, w którym czuję się komfortowo.)

yitzih
źródło
1
„Innym problemem, jaki mam, jest to, że 2 osoby dostają blokadę dla tego samego przedmiotu, jednak uważam, że jest to warunek wyścigu, w którym czuję się komfortowo” - użycie transakcji bazy danych wokół zdobycia blokady powinno zapobiec takim warunkom wyścigu.
Jules
Większość silników baz danych (przynajmniej typu relacyjnego) ma wbudowaną obsługę tego. Jest to bardzo powszechna koncepcja w świecie RDBMS, a nawet „zabawkowe” bazy danych radzą sobie z tym wystarczająco dobrze, biorąc pod uwagę, że mówisz, że chcesz optymistycznego lub pesymistycznego blokowania. W każdym razie, nie sądzę, że jest to coś, co trzeba zbudować w jakikolwiek sposób: sprawdź opcje w silniku db, aby zobaczyć, jak z nim pracować.
jleach
Fakt, że twoja aplikacja jest aplikacją komputerową ( gruby klient ), nie robi dużej różnicy. Można go zaprojektować w taki sam sposób, jak wysoce dostępną aplikację serwerową z wieloma instancjami.
Hosam Aly,

Odpowiedzi:

19

Jedną z rzeczy, która pomoże ci tutaj, jest terminologia. To, co tu opisujesz, nazywa się „blokowaniem pesymistycznym”. Główną alternatywą dla tego podejścia jest „optymistyczne blokowanie”. W przypadku pesymistycznego blokowania każdy aktor musi zablokować rekord przed aktualizacją i zwolnić blokadę po zakończeniu aktualizacji. W optymistycznym blokowaniu zakładasz, że nikt inny nie aktualizuje rekordu i próbujesz. Aktualizacja kończy się niepowodzeniem, jeśli rekord został zmieniony przez innego aktora.

Optymistyczne blokowanie jest generalnie preferowane, jeśli szansa, że ​​dwóch aktorów zaktualizuje to samo w tym samym czasie, jest niska. Pesymistyczne jest zwykle stosowane, gdy ta szansa jest duża lub musisz wiedzieć, że aktualizacja będzie w stanie się powieść przed rozpoczęciem. Z mojego doświadczenia wynika, że ​​optymistyczne blokowanie jest prawie zawsze preferowane, ponieważ istnieje wiele problemów związanych z blokowaniem pesymistycznym. W jednym z pytań poruszono jeden z największych problemów. Użytkownicy mogą zablokować zapis do edycji, a następnie wyjść na lunch. Twoje łagodzenie pomoże w tym, ale wrażenia użytkownika nie będą lepsze niż optymistyczne podejście i prawdopodobnie będzie znacznie gorsze. Na przykład jeden użytkownik otwiera rekord, zaczyna go aktualizować, a szef pojawia się przy biurku. Inny użytkownik próbuje edytować rekord. Jest zamknięta. Drugi użytkownik próbuje i po 5 minutach blokada wygasa, a drugi użytkownik aktualizuje rekord. Pierwszy użytkownik wraca do ekranu, próbuje zapisać i mówi, że zgubił blokadę. Teraz w tym samym scenariuszu, z tym samym wszystkim, z wyjątkiem optymistycznego blokowania, wrażenia pierwszego użytkownika są prawie takie same, ale drugi użytkownik nie czeka 5 minut.

Schemat, który określiłeś, zostałby znacznie ulepszony przez wdrożenie optymistycznego blokowania dla wartości blokady, ale moje przeczucie jest takie, że optymistyczne blokowanie jest prawdopodobnie OK dla całej rzeczy i możesz pozbyć się pola is_locked.

Nie podajesz używanej „bazy danych w chmurze”. Prawdopodobnie powinieneś przyjrzeć się tym funkcjom, aby sprawdzić, czy są do tego wbudowane funkcje przed wdrożeniem własnego rozwiązania.

Oto podstawowa recepta: zamiast pola is_locked masz pole numeru wersji. Podczas odzyskiwania rekordu pobierana jest bieżąca wersja rekordu. Podczas aktualizacji uzależniasz aktualizację od pola wersji zgodnego z pobraną wersją i zwiększasz ją po pomyślnym zakończeniu. Jeśli wersja się nie zgadza, aktualizacja nie ma żadnego skutku i zgłaszasz ją z powrotem jako awarię.

JimmyJames
źródło
To bardzo pomocna odpowiedź. Czy możesz wyjaśnić, dlaczego pesymistyczne blokowanie jest odradzane, gdy istnieje niewielka szansa na „kolizje”. Czy to tylko dlatego, że wymaga przejścia do bazy danych, aby rozpocząć edycję, czy z powodu dodatkowej złożoności lub z innego powodu? Dzięki!
yitzih
3
@yitzih Niektórzy sugerowali lekturę: Fowler i in., Patterns of Enterprise Application Architecture . Istnieje cały rozdział na ten temat, z dobrym omówieniem wszystkich opcji i powodów ich wyboru.
Jules
2
@ Jimmy - Twoja odpowiedź jest w porządku. W niektórych przypadkach zgłoszenie błędu nie jest wystarczające. Rozważ przypadek, w którym użytkownik poświęca kilka minut na aktualizację rekordu. W takim przypadku samo niepowodzenie może nie być wystarczająco dobre, można dać użytkownikowi możliwość połączenia zmian w lotach z tymi, które zostały popełnione przez innego użytkownika. Powinienem powiedzieć, że optymistyczne blokowanie może wymagać rozwiązania konfliktu w zależności od twoich wymagań.
Jon Raynor,
3
Warto wspomnieć, że pesymistyczne blokowanie jest dużo łatwiejsze do wyjaśnienia klientowi. Jeśli napiszesz wiadomość, że klient nie może uzyskać dostępu do rekordu, ponieważ jest on obecnie edytowany przez inny, klient zarówno dobrze rozumie, jak i ogólnie go akceptuje. Jeśli zamiast tego powiesz klientowi po zapisaniu, że zapisanie nie było możliwe, ponieważ zostało już zaktualizowane przez innego użytkownika 7/10, klient będzie sfrustrowany i / lub spodziewa się wyjaśnienia tego dziwnego zachowania programu.
Neil
2
@ Neil To prawda i myślę, że często dlatego pesymistyczne blokowanie jest stosowane, gdy optymistyczne jest bardziej odpowiednie. Często przepływ pracy sprawia, że ​​bardzo mało prawdopodobne jest kolizja.
JimmyJames
0

Z odpowiedzi @ JimmyJames możemy zobaczyć, jak naprawdę pytanie dotyczy doświadczenia użytkownika .

Wszystko zależy od kontekstu. Ile czasu i wysiłku wymaga aktualizacja rekordu? Jak często wielu użytkowników chce aktualizować ten sam dokument?

Na przykład, jeśli Twoi użytkownicy zwykle aktualizują rekord przez kilka sekund, a rywalizacja jest niewielka, prawdopodobnie optymistyczne blokowanie jest dobrym rozwiązaniem. W najgorszym przypadku użytkownik będzie musiał poświęcić kilka sekund, może nawet minutę, na aktualizację dokumentu.

Jeśli twój dokument jest bardzo kontrowersyjny, ale ma dobrą strukturę, być może możesz zezwolić mu na blokowanie poszczególnych pól w odstępach 30-sekundowych, pokazując licznik czasu lub dyskretne powiadomienie, aby umożliwić im przedłużenie blokady.

Jeśli jednak użytkownicy spędzają dużo czasu lub wysiłku, należy rozważyć inne podejścia. Czy twoja płyta ma dobrą strukturę? Czy możesz pokazać użytkownikom porównanie (różnicę) między wersją na serwerze a wersją, którą próbują zapisać? Czy możesz wyróżnić różnice? Czy możesz pozwolić im scalić zmiany? Pomyśl o doświadczeniu, jakie chcesz mieć dzięki narzędziom kontroli źródła. Naprawdę nie chcesz być zmuszany do napisania całego tego kodu ponownie!

Możesz zajrzeć do Dokumentów Google, aby uzyskać dodatkową inspirację. Być może możesz pokazać użytkownikom powiadomienie o zapisaniu nowej wersji. Może pokażesz im, ile osób ma otwarty rekord, aby mogli wrócić w mniej spornym momencie.

Hosam Aly
źródło