Firebird 2.1.1 Trigery , kolejnosc wywolywania

0

Witam!
Przy pomocy trigerów zmieniam w systemie stany magazynowe. Program wykonuje pewne zapytania,
sprawdzenie stanu w tabeli dodanie lub odjęcie do tego stanu określonej ilości i update na tej tabeli. No i moje pytanie jest takie, czy trigery wywoływane z tej samej tabeli sa wykonywane równolegle przez silnik bazy czy zawsze po kolei, jeden baza wykona to bierze kolejny z kolejki i go wykonuje? Pytam ponieważ przestawiam system na pracę w sieci i zawsze musze założyć skrajne przypadki a skrajny przypadek to taki w ktorym 20 roznych osob zapisuje rekord wywolujacy ten sam triger ktory wlasnie zmienia stany magazynowe. Nie chcialbym by dwa sprawdzily stan magazynowy pobierajac ilosc 10 , jeden do 10 doda 5 i zapisze 15, drugi do 10 doda 3 i zapisze 13 pozostawiajac na koncu 13 zamiast sytuacji gdzie pierwszy wezmie 10 doda 5 zostawi 15, drugi wykonujacy sie w kolejce wezmie 15 i doda 3 pozostawiajac dla kolejnego 18.
Wyjsciem jest robienie select for update na tabeli ze stanem na poczatku trigera ale czy jest to konieczne bo jezeli wykonywane to jest w calosci w kolejne nie rownolegle to chyba sensu nie ma.
Nie bardzo jest jak przetestowac dwa przypadki bo nie zatrzymam trigery w polowie na zalowanie
pozdrawiam

P.

0

jak chcesz mieć pewność to załóż ograniczenie na pole, że wartość nie może być < 0. Wtedy przy próbie wydania więcej niż jest dostaniesz błąd, który pozostaje obsłużyć odpowiednio. Przy takim sprawdzaniu jak chcesz zrobić zawsze jest szansa, że między select a update ktoś inny zrobi update

0

Jak ktos bedzie recznie grzebal w bazie to jego problem, jak pisalem mogę się tutaj zabe@ieczecac blokadami, ale moje pytanie było inne i konkretne czy trigery sa przez baze wykonywane po kolei w calosci czy rownolegle

0

poczytaj o poziomie izolacji transakcji. W momencie jak robisz UPDATE twoja transakcja widzi jakiś stan bazy. Jaki to zależy min. od wspomnianego poziomu izolacji transakcji.
Wyobraź sobie taką sytuację (mamy dwa kompy - A i B, które próbują zmienić stan magazynu)

  1. A pyta o stan magazynu i stwierdza, że jest go na tyle, że można go zmienić
  2. B pyta o stan magazynu i stwierdza, że jest go na tyle, że można go zmienić
  3. A zmienia stan magazynu (jest go teraz za mało dla komputera B)
  4. B zmienia stan magazynu i mamy minus
    Drogi są dwie - albo przy próbie zmiany B dostanie error (np. jeśli założysz ograniczenie na stan > 0, albo odpowiednio zadziałasz blokadami na rekord) albo dostanie minus i wszyscy będą "zadowoleni". Przy dwóch działających stanowiskach prawdopodobieństwo będzie stosunkowo małe, ale im więcej stanowisk i zmian magazynu tym częściej będą się takie sytuacje zdażać.

Na koniec trigery/procedury/cokolwiek nie są kolejkowane. O ile jeśli masz jeden rdzeń to fizycznie nie jest możliwe wykonanie dwóch operacji w tym samym czasie o tyle nikt nie zagwarantuje, że CAŁY kod trigera wykona się na raz (system może wywłaszczyć w połowie wątek triggera A i uruchomić wątek triggera B). Jeśli masz kilka rdzeni to to ograniczenie znika i tutaj już nie masz co marzyć o jakimkolwiek kolejkowaniu.

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