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ć