How can I make the following controller threadsafe in rails 4 with postgresql:
def controller_action
if Model.exists(column_name:"some_value")
else
@model=Model.new(column_name:"some_value")
@model.save
end
end
I am running puma, so my concern is that if two threads run this controller at the same time, and a row doesn't exist with the specified value of column_name, two records will be created whereas I only want 1.
Contrary to the comments, concurrent inserts on the same table are entirely permissible in PostgreSQL, so there's a race condition here.
To make this safe you must have a unique
constraint (or primary key
) on column_name
. Duplicate inserts will then throw an exception which you can catch and retry with an update.
If you don't have a unique constraint, then you must LOCK TABLE ... IN EXCLUSIVE MODE
to prevent concurrent upserts. Or use one of the concurrency-safe methods described in:
How to UPSERT (MERGE, INSERT ... ON DUPLICATE UPDATE) in PostgreSQL?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With