Transakcje, blokowanie po select

0

Witam, mam pytanie, jeżeli mam taką przykładową transakcje, która sprawdza jakąś wartość i jeżeli spełnia to zmienia tę wartość, jak mam się wystrzec przed przykładem:

Transakcja 1 : Sprawdza IF, spełnia
Transakcja 2 : Sprawdza IF, spełnia
Transakcja 1: Updatuje wartość
Transakcja 2: Updatuje.
A chciałbym żeby transakcja podczas robienia SELECT lockowała wiersz/tabele

BEGIN TRANSACTION 
    if((select Oszczednosci.wartosc from Oszczednosci where ID = 1)>= 25000)
        begin
                        // tu coś robi
                        ...
            update Oszczednosci set wartosc = wartosc - 25000 where ID = 1; 
        end
    COMMIT
3

if (select count(*) from tabela where id=1 and wartosc >= 2500 for update > 0)
{
...
}

0

czyli po prostu for update rozwiązuje sprawe? dziękuje

1

tak, bo blokuje dane rekordy do czasu zakończenia transakcji, w której blokada została nałożona

2

Można jeszcze wspomnieć o tym, że niektóre silniki pozwalają dla SELECT FOR UPDATE dodać klauzulę: SKIP LOCKED ROWS albo NOWAIT, albo WAIT <timeout>.
Czasem może być to przydatne:

  • SKIP LOCKED ROWS (np. mamy wielu konsumentów danych z tabelki - coś a'la kolejka i nie interesuje nas, który konsument przetworzy, ważne żeby inni mogli przetwarzać współbieżnie, bez zbędnych przerw)
  • NOWAIT (jak coś zablokowało wiersze do aktualizacji, to od razu szybki fail)
  • WAIT 5 (failure po 5 sekundach, np. żeby nie blokować wątków aplikacji dłużej niż no konieczne z jakiegoś względu)

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