How to make ActiveRecord ThreadSafe

感情迁移 提交于 2019-12-18 03:43:30

问题


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.


回答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?




回答2:


Assume that threads have a 1:1 relationship with connections. So if you have 100 threads that need to access the database, you should crank the connection pool up to 100. If you have more worker threads than connections, you need to use a Queue (or some other thread safe data structure) to manage communication between them.



来源:https://stackoverflow.com/questions/22211547/how-to-make-activerecord-threadsafe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!