Sim e Não - como de costume, depende. A documentação diz estritamente que:
Em outras palavras, simplesmente SELECT difere de SELECT FOR UPDATE/DELETE/UPDATE.
Você pode criar um caso de teste simples para observar esse comportamento:
Sessão 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=>
Agora faça login em outra Sessão 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;
Após o último comando
SELECT ... FOR UPDATE
a sessão 1 "trava" e está esperando algo ...... De volta à sessão 1
test=> insert into test select * from generate_series(1,10);
INSERT 0 10
test=> commit;
COMMIT
E agora, quando você voltar para a sessão 2, verá isto:
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)
Isto é - simples
SELECT
ainda não vê nenhuma alteração, enquanto SELECT ... FOR UPDATE
vê que as linhas foram excluídas. Mas não vê novas linhas inseridas pela sessão 1Na verdade, uma sequência que você está vendo é:
- processo A inicia sua transação
- processo A exclui tudo da tabela T
- processo B inicia sua transação
- o processo B tenta uma seleção para atualização em uma linha na tabela T
- processo B "trava" e está esperando até que a sessão A faça um commit ou rollback
- processo A repovoa a tabela T dos dados recebidos
- processo A confirma sua transação
- o processo B aparece vazio (0 linhas - após o commit da sessão A) e chama o rollback