Tak i Nie - jak zwykle to zależy. Dokumentacja ściśle mówi, że:
Innymi słowy, po prostu SELECT różni się od SELECT FOR UPDATE/DELETE/UPDATE.
Możesz utworzyć prosty przypadek testowy, aby zaobserwować to zachowanie:
Sesja 1
test=> START TRANSACTION;
START TRANSACTION
test=> SELECT * FROM test;
x
----
1
2
3
4
5
6
7
8
9
10
(10 rows)
test=> DELETE FROM test;
DELETE 10
test=>
Teraz zaloguj się w innej sesji 2:
test=> START TRANSACTION;
START TRANSACTION
test=> SELECT * FROM test;
x
----
1
2
3
4
5
6
7
8
9
10
(10 rows)
test=> SELECT * FROM test WHERE x = 5 FOR UPDATE;
Po ostatnim poleceniu SELECT ... FOR UPDATE
sesja 1 "zawiesza się" i czeka na coś ......
Powrót do sesji 1
test=> insert into test select * from generate_series(1,10);
INSERT 0 10
test=> commit;
COMMIT
A teraz, gdy wrócisz do sesji 2, zobaczysz to:
test=> SELECT * FROM test WHERE x = 5 FOR UPDATE;
x
---
(0 rows)
test=> select * from test;
x
----
1
2
3
4
5
6
7
8
9
10
(10 rows)
To znaczy - prosty SELECT
nadal nie widzi żadnych zmian, podczas gdy SELECT ... FOR UPDATE
widzi, że wiersze zostały usunięte. Ale nie widzi nowych wierszy wstawionych przez sesję 1
W rzeczywistości sekwencja, którą widzisz, to:
- proces A rozpoczyna transakcję
- proces A usuwa wszystko z tabeli T
- proces B rozpoczyna transakcję
- proces B próbuje dokonać wyboru w celu aktualizacji jednego wiersza w tabeli T
- proces B „zawiesza się” i czeka, aż sesja A wykona zatwierdzenie lub wycofanie
- proces A ponownie wypełnia tabelę T z przychodzących danych
- proces A zatwierdza swoją transakcję
- proces B jest pusty (0 wierszy – po zatwierdzeniu sesji A) i wywołuje wycofanie