Ja und Nein – wie immer kommt es darauf an. Die Dokumentation sagt streng, dass:
Mit anderen Worten, SELECT unterscheidet sich einfach von SELECT FOR UPDATE/DELETE/UPDATE.
Sie können einen einfachen Testfall erstellen, um dieses Verhalten zu beobachten:
Sitzung 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=>
Jetzt in einer anderen Sitzung anmelden 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;
Nach dem letzten Befehl SELECT ... FOR UPDATE
Sitzung 1 "hängt" und wartet auf etwas ......
Zurück in Sitzung 1
test=> insert into test select * from generate_series(1,10);
INSERT 0 10
test=> commit;
COMMIT
Und jetzt, wenn Sie zu Sitzung 2 zurückkehren, sehen Sie Folgendes:
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)
Das heißt - einfach SELECT
sieht immer noch keine Änderungen, während SELECT ... FOR UPDATE
sieht, dass Zeilen gelöscht wurden. Aber es sieht keine neuen Zeilen, die von Sitzung 1 eingefügt wurden
Tatsächlich ist eine Sequenz, die Sie sehen, folgende:
- Prozess A startet seine Transaktion
- Prozess A löscht alles aus Tabelle T
- Prozess B startet seine Transaktion
- Prozess B versucht eine Auswahl zur Aktualisierung einer Zeile in Tabelle T
- Prozess B "hängt" und wartet, bis Sitzung A einen Commit oder Rollback durchführt
- Prozess A füllt Tabelle T mit eingehenden Daten neu
- Prozess A schreibt seine Transaktion fest
- Prozess B ist leer (0 Zeilen - nach dem Festschreiben von Sitzung A) und ruft Rollback auf