Ja och nej – som vanligt beror det på. Dokumentationen säger strikt att:
Med andra ord, helt enkelt SELECT skiljer sig från SELECT FOR UPDATE/DELETE/UPDATE.
Du kan skapa enkla testfall för att observera det beteendet:
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=>
Logga in nu i en annan 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 det sista kommandot SELECT ... FOR UPDATE
session 1 "hänger" och väntar på något ......
Tillbaka i session 1
test=> insert into test select * from generate_series(1,10);
INSERT 0 10
test=> commit;
COMMIT
Och nu när du går tillbaka till session 2 kommer du att se detta:
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 vill säga - enkel SELECT
ser fortfarande inga ändringar, medan SELECT ... FOR UPDATE
ser att rader har tagits bort. Men den ser inte nya rader infogade av session 1
Faktum är att en sekvens du ser är:
- process A startar sin transaktion
- process A tar bort allt från tabell T
- process B startar sin transaktion
- process B försöker välja för uppdatering på en rad i tabell T
- process B "hänger sig" och väntar tills session A gör en commit eller rollback
- process A fyller på tabell T från inkommande data
- process A genomför sin transaktion
- process B visas tom (0 rader - efter session A commit) och anropar återställning