Eu quero fazer algo assim:
begin;
select * from foos where owner_id=123 and unread=true order by id for update;
update foos set unread=false where owner_id=123 and unread=true;
commit;
O objetivo é evitar deadlock quando dois processos executam o UPDATE simultaneamente. Problema descrito mais aqui: Por que estou recebendo um impasse para uma única consulta UPDATE?
Na declaração onde adquiro o bloqueio, não preciso de nenhuma informação sobre as linhas. Eu só quero bloquear essas linhas específicas. Existe uma maneira de fazer isso (elegante ou hacky) que diz ao postgres para não fazer nenhum trabalho de realmente me fornecer os dados?
Sobre o objetivo de evitar impasses: veja minha resposta à sua pergunta relacionada:
Sobre a pergunta do título:
Use uma lista vazia (mais curta, mais barata)
SELECT
com uma cláusula de bloqueio em uma subconsulta e executecount()
no exteriorSELECT
:Dessa forma, você obtém uma única linha de resultado com o número de linhas bloqueadas. Todas as linhas selecionadas na subconsulta são bloqueadas durante a transação. (Você pode abortar em caso de
0
linhas.)Apartes:
and unread=true
é apenas uma maneira barulhenta de dizerAND unread
.unread
puder serNULL
, considereunread IS NOT TRUE
em vez disso.