Ruby on rails 如何使ActiveRecord线程安全
如何使用postgresql使rails 4中的以下控制器线程安全:Ruby on rails 如何使ActiveRecord线程安全,ruby-on-rails,postgresql,ruby-on-rails-4,thread-safety,rails-activerecord,Ruby On Rails,Postgresql,Ruby On Rails 4,Thread Safety,Rails Activerecord,如何使用postgresql使rails 4中的以下控制器线程安全: def controller_action if Model.exists(column_name:"some_value") else @model=Model.new(column_name:"some_value") @model.save end end 我正在运行puma,所以我担心的是,如果两个线程同时运行此控制器,并且不存在具有指定列名称值的行,则将创建两条记录,而我只需要1条记录。
def controller_action
if Model.exists(column_name:"some_value")
else
@model=Model.new(column_name:"some_value")
@model.save
end
end
我正在运行puma,所以我担心的是,如果两个线程同时运行此控制器,并且不存在具有指定列名称值的行,则将创建两条记录,而我只需要1条记录。假设线程与连接具有1:1的关系。因此,如果您有100个线程需要访问数据库,那么您应该将连接池调到100个。如果工作线程多于连接,则需要使用队列(或其他线程安全的数据结构)来管理它们之间的通信。与注释相反,PostgreSQL完全允许在同一个表上同时插入,因此这里存在争用条件 为确保安全,您必须在
列名
上设置唯一
约束(或主键
)。重复插入将抛出一个异常,您可以捕获该异常并通过更新重试
如果没有唯一约束,则必须锁定表。。。在独占模式下
以防止并发上传。或者使用以下中描述的并发安全方法之一:
Postgres将锁定事务,因此第一个事务将在db层阻止第二个事务。这是传统上处理这种竞争条件的方式。你的问题实际上与线程无关,你有一个普通的竞争条件。解决方案是在数据库中添加一个约束,并处理不可避免的异常(即将逻辑放在它所属的数据库中)。因此,让我确保我理解这一点……一个线程赢得竞争条件并首先执行Model.exists;同时,另一个线程被锁定。@model.save postgresql移除锁后,另一个线程会看到现在存在一个具有所需值的行。如果这就是它的工作原理,那么postgresql如何知道何时移除锁?它是否总是等到控制器中的所有逻辑完成后再打开锁?@TheIrishGuy胡说八道。并发更新会被锁定。并发插入不会相互阻塞。看见