Ano a Ne - jako obvykle, záleží. Dokumentace přesně říká, že:
Jinými slovy, jednoduše SELECT se liší od SELECT FOR UPDATE/DELETE/UPDATE.
Můžete vytvořit jednoduchý testovací případ a pozorovat toto chování:
Relace 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=>
Nyní se přihlaste v další relaci 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 posledním příkazu SELECT ... FOR UPDATE
relace 1 "visí" a na něco čeká ......
Zpět v relaci 1
test=> insert into test select * from generate_series(1,10);
INSERT 0 10
test=> commit;
COMMIT
A teď, když se vrátíte k relaci 2, uvidíte toto:
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)
Tedy - jednoduché SELECT
stále nevidí žádné změny, zatímco SELECT ... FOR UPDATE
vidí, že řádky byly smazány. Nevidí však nové řádky vložené relací 1
Ve skutečnosti sekvence, kterou vidíte, je:
- proces A zahájí svou transakci
- proces A odstraní vše z tabulky T
- proces B zahájí svou transakci
- proces B se pokusí vybrat aktualizaci jednoho řádku v tabulce T
- proces B se „zasekne“ a čeká, dokud relace A neprovede potvrzení nebo vrácení zpět
- proces A znovu naplní tabulku T z příchozích dat
- proces A potvrdí svou transakci
- proces B je prázdný (0 řádků – po potvrzení relace A) a volá rollback