snippetsqlMinor
How can I lock rows FOR UPDATE without returning data over the connection?
Viewed 0 times
rowscanwithoutupdatethereturningforhowdataover
Problem
I want to do something like this:
The goal is to avoid deadlock when two processes execute the UPDATE simultaneously. Problem described more here: Why am I getting a deadlock for a single UPDATE query?
In the statement where I acquire the lock, I don't need any info about the rows. I just want to lock those particular rows. Is there a way to do this (elegant or hacky) which tells postgres to not do any of the work of actually giving me the data?
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;
The goal is to avoid deadlock when two processes execute the UPDATE simultaneously. Problem described more here: Why am I getting a deadlock for a single UPDATE query?
In the statement where I acquire the lock, I don't need any info about the rows. I just want to lock those particular rows. Is there a way to do this (elegant or hacky) which tells postgres to not do any of the work of actually giving me the data?
Solution
About the goal to avoid deadlocks: see my answer to your related question:
About the question in the title:
Use an empty (shortest, cheapest)
This way you get a single result row with the number of locked rows. All rows selected in the subquery are locked for the duration of the transaction. (You can abort in case of
Asides:
- Why am I getting a deadlock for a single UPDATE query?
About the question in the title:
Use an empty (shortest, cheapest)
SELECT list with a locking clause in a subquery, and run count() in the outer SELECT:SELECT count(*) AS locked_rows
FROM (
SELECT FROM foos
WHERE owner_id = 123
AND unread
ORDER BY id
FOR UPDATE -- !
) sub;This way you get a single result row with the number of locked rows. All rows selected in the subquery are locked for the duration of the transaction. (You can abort in case of
0 rows.)Asides:
and unread=trueis just a noisy way of sayingAND unread.
- If
unreadcan beNULL, considerunread IS NOT TRUEinstead.
Code Snippets
SELECT count(*) AS locked_rows
FROM (
SELECT FROM foos
WHERE owner_id = 123
AND unread
ORDER BY id
FOR UPDATE -- !
) sub;Context
StackExchange Database Administrators Q#257188, answer score: 5
Revisions (0)
No revisions yet.