[FireBird/Inne] Blokowanie rekordu w bazie

0

Witam.

Czy jest jakaś możliwość oznaczenia rekordu w FireBirdzie (lub innej bazie) że jest przez kogoś edytowany? Do tej pory robiłem tak, że w tabeli miałem dodatkowe pole STATUS i tam przed edycją robiłem update ustawiając odpowiednią flagę. Ale to nie jest do końca "bezpieczne" rozwiązanie, bo zawsze coś może pójść nie tak, czy to komp sie wyłączy, czy połączenie zerwie czy też jakieś moje niedopatrznie w kliencie i wtedy taki rekord "wisi" zablokowany. Czyli, zrywa się połączenie (lub użytkownik przestaje edytować) i rekord zostaje automatycznie odblokowany (tak jak w transakcjach - przy zerwaniu połączenia, serwer robi rollback). FireBird 2.1 wprowadza wiele nowości, zastanawiam się czy jest na to jakiś szybki sposób? Myślałem jakoś pokombinować z tablicami tymczasowymi, bo są chyba usuwane jak zerwie się połączenie, ale może jest jakiś lepszy sposób?

Pozdrawiam

0

Jest bezpieczne, jeśli robisz to w transakcji.

0

Na szybko napiszę bo akurat przerabiam prockę do blokad.

Po pierwsze jest możliwość blokowania rekordu wykorzystując mechanizmy Firebird'a. Robisz po prostu 'dummy update' czyli UPDATE TABELKA SET ID=ID. Są jeszcze jakieś opcje FOR UPDATE itd.

Ja częściej stosuję rozwiazanie z tabelką z boku, tak w skrócie: zazwyczaj mam tabele:

OPERATORZY (IDOPERATORA ...)
SESJE (IDSESJI, IDOPERATORA, OSTATNIAAKTYWNOSC ...)
BLOKADY (IDBLOKADY, IDSESJI, IDTYP, IDOBJ) + UNIQUE(IDTYP, IDOBJ)

Funkcja zakładająca blokadę:

  • całość w 1 transakcji
    • całość w try except na wypadek naruszenia indeksu unikalnego
  • sprawdzasz czy blokada istnieje (idtyp, idobj)
    • nie istnieje => INSERT INTO BLOKADY
    • istnieje
      • sprawdzasz czy sesja z której założono blokadę jest jeszcze aktywna (wykluczy to jakieś wiszące sesje, oczywiścię w grę wchodzi interwał uaktualniania sesji)
        • aktywna => wyświetlasz ładny komunikat "Pozycja zablokowana przez XXXX o XXXX
        • nie aktywna => UPDATE BLOKADY

Zalety:

  • dzięki indeksowi unikalnemu i zastosowaniu transakcji masz 100% że dwa razy nie założysz blokady
  • nie modyfikujesz tabeli chronionej (a czasem jak są na niej jakieś triggery, to nie jest pożądane)
  • jak już się coś spieprzy, i komuś się nie będzie chciało czekać aż upłynie interwał uaktualniania sesji, to robisz formatkę listy (dostępną dla adminów) z założonymi blokadami, które to z tego poziomu można usunąć.

Rozwiązanie sprawdzone. Co więcej, uniwersalny mechanizm blokad możesz wykorzystywać do zapewnienia wykonania pewnych procesów, które chcesz aby można było wykonywać najwyżej w jednej instancji na poziomie całej bazy. Aha, do funkcji zakładającej blokadę, przekazuję jeszcze boolean'a który mówi czy ma być komunikat czy nie.
Usunięcia blokady chyba nie trzeba opisywać ...

Pozdrawiam

P.S. Cała logika zakładania blokady, dobrze jak jest w stored procce na serwerze, żeby dwa razy do bazy nie pukać

0

@TBSO: Też o tym myślałem, ale wtedy możliwe jest edytowanie tylko jednego dokumentu/rekordu jednocześnie przez tego samego użytkownika.

@Bobik: No zaskoczyłeś mnie tym. Faktycznie, nigdy nie myślałem żeby podejść do tego od tej strony. To może się udać :D

1 użytkowników online, w tym zalogowanych: 0, gości: 1