Ja og nej – det afhænger som sædvanligt. Dokumentationen siger strengt taget at:
Med andre ord, blot SELECT adskiller sig fra SELECT FOR UPDATE/DELETE/UPDATE.
Du kan oprette en simpel testcase for at observere denne adfærd:
Session 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 ind i en anden session 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;
Efter den sidste kommando SELECT ... FOR UPDATE
session 1 "hænger" og venter på noget ......
Tilbage i session 1
test=> insert into test select * from generate_series(1,10);
INSERT 0 10
test=> commit;
COMMIT
Når du nu går tilbage til session 2, vil du se dette:
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)
Det vil sige - simpel SELECT
kan stadig ikke se nogen ændringer, mens SELECT ... FOR UPDATE
ser, at rækker er blevet slettet. Men den ser ikke nye rækker indsat af session 1
Faktisk er en sekvens du ser:
- proces A starter sin transaktion
- proces A sletter alt fra tabel T
- proces B starter sin transaktion
- proces B forsøger at vælge til opdatering på én række i tabel T
- proces B "hænger" og venter, indtil session A foretager en commit eller rollback
- proces A genudfylder tabel T fra indgående data
- proces A forpligter sin transaktion
- proces B vises tom (0 rækker - efter session A commit) og kalder rollback