What you need to block
In your case, you need to lock the row containing the maximum survey_complete_sequence , as this is the row that each query will look for when it gets the required value.
maxval =AnswerHeader.maximum('survey_complete_sequence')
Is it possible to lock one row, not an entire table
Such a scenario does not exist for your scenario. But you can use Postgresql SELECT FOR UPDATE row level locking .
To get exclusive row-level locking in a row without changing the row, select the row using SELECT FOR UPDATE.
And you can use a pessimistic lock on the rails and specify which lock you will use.
Call blocking (“some kind of blocking clause”) to use a database-specific lock, such as “LOCK IN SHARE MODE” or “FOR UPDATE NOWAIT”
Here is an example of how to achieve this from the official rails guide
Item.transaction do i = Item.lock("LOCK IN SHARE MODE").find(1) ... end
Relations using locks are usually wrapped inside a transaction to prevent deadlock conditions.
So what you need to do -
- Apply
SELECT FOR UPDATE lock to row consisting of maximum('survey_complete_sequence') - Get the required value from this line
- Update
AnswerHeader with accepted value
source share