In my Rails 4 app, I have this query to a Postgres 9.4 database:
@chosen_opportunity = Opportunity.find_by_sql(
" UPDATE \"opportunities\" s
SET opportunity_available = false
FROM (
SELECT \"opportunities\".*
FROM \"opportunities\"
WHERE ( deal_id = #{@deal.id}
AND opportunity_available = true
AND pg_try_advisory_xact_lock(id) )
LIMIT 1
FOR UPDATE
) sub
WHERE s.id = sub.id
RETURNING sub.prize_id, sub.id"
)
Very much inspired by this related answer on dba.SE.
I just want my query to find and update the first (randomly, with LIMIT
) row where available = true
and update it to available = false
, and I need to lock the row while doing this, but without making new requests waiting for the release of the previous lock as there are many concurrent calls that will use this query.
But I also saw the NOWAIT
option to FOR UPDATE
. I'm not sure I understand the difference between using pg_try_advisory_xact_lock()
and the NOWAIT
option, they seem to me to achieve the same goal:
NOWAIT
's goal:To prevent the operation from waiting for other transactions to commit, use the
NOWAIT
option.pg_try_advisory_xact_lock
's goal
is not to wait for the previous transaction to release the lock and still be able to do another transaction and only operate the next select for update the 'not yet locked' rows.
Which one is better suited to my need?