Ja en Nee - zoals gewoonlijk hangt het ervan af. De documentatie zegt strikt dat:
Met andere woorden, gewoon SELECT verschilt van SELECT FOR UPDATE/DELETE/UPDATE.
U kunt een eenvoudige testcase maken om dat gedrag te observeren:
Sessie 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=>
Log nu in op een andere Sessie 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;
Na het laatste commando SELECT ... FOR UPDATE
sessie 1 "hangt" en wacht op iets ......
Terug in sessie 1
test=> insert into test select * from generate_series(1,10);
INSERT 0 10
test=> commit;
COMMIT
En als je nu teruggaat naar sessie 2, zie je dit:
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)
Dat wil zeggen - eenvoudig SELECT
ziet nog steeds geen wijzigingen, terwijl SELECT ... FOR UPDATE
ziet wel dat rijen zijn verwijderd. Maar er worden geen nieuwe rijen ingevoegd door sessie 1
In feite is een reeks die u ziet:
- proces A begint zijn transactie
- proces A verwijdert alles uit tabel T
- proces B start zijn transactie
- proces B probeert een selectie voor update op één rij in tabel T
- proces B "hangt" en wacht tot sessie A een commit of rollback doet
- proces A vult tabel T opnieuw met inkomende gegevens
- proces A voert zijn transactie uit
- proces B wordt leeg weergegeven (0 rijen - na vastlegging van sessie A) en roept rollback op