如何使 ActiveRecord 线程安全 [英] How to make ActiveRecord ThreadSafe

查看:31
本文介绍了如何使 ActiveRecord 线程安全的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用 postgresql 在 rails 4 中使以下控制器线程安全:

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

我正在运行 puma,所以我担心的是,如果两个线程同时运行此控制器,并且不存在具有 column_name 指定值的行,则会创建两条记录,而我只想要 1.

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.

推荐答案

与评论相反,在 PostgreSQL 中完全允许在同一个表上并发插入,因此这里存在竞争条件.

Contrary to the comments, concurrent inserts on the same table are entirely permissible in PostgreSQL, so there's a race condition here.

为了确保安全,您必须在 column_name 上有一个 unique 约束(或 primary key).重复插入将引发异常,您可以捕获该异常并通过更新重试.

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.

如果您没有唯一约束,那么您必须LOCK TABLE ... IN EXCLUSIVE MODE 以防止并发更新插入.或者使用以下描述的并发安全方法之一:

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:

如何UPSERT(MERGE, INSERT ... ON DUPLICATE UPDATE) 在 PostgreSQL 中?

这篇关于如何使 ActiveRecord 线程安全的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆