Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何使ActiveRecord线程安全_Ruby On Rails_Postgresql_Ruby On Rails 4_Thread Safety_Rails Activerecord - Fatal编程技术网

Ruby on rails 如何使ActiveRecord线程安全

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条记录。

如何使用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条记录。

假设线程与连接具有1:1的关系。因此,如果您有100个线程需要访问数据库,那么您应该将连接池调到100个。如果工作线程多于连接,则需要使用队列(或其他线程安全的数据结构)来管理它们之间的通信。

与注释相反,PostgreSQL完全允许在同一个表上同时插入,因此这里存在争用条件

为确保安全,您必须在
列名
上设置
唯一
约束(或
主键
)。重复插入将抛出一个异常,您可以捕获该异常并通过更新重试

如果没有唯一约束,则必须
锁定表。。。在独占模式下
以防止并发上传。或者使用以下中描述的并发安全方法之一:


Postgres将锁定事务,因此第一个事务将在db层阻止第二个事务。这是传统上处理这种竞争条件的方式。你的问题实际上与线程无关,你有一个普通的竞争条件。解决方案是在数据库中添加一个约束,并处理不可避免的异常(即将逻辑放在它所属的数据库中)。因此,让我确保我理解这一点……一个线程赢得竞争条件并首先执行Model.exists;同时,另一个线程被锁定。@model.save postgresql移除锁后,另一个线程会看到现在存在一个具有所需值的行。如果这就是它的工作原理,那么postgresql如何知道何时移除锁?它是否总是等到控制器中的所有逻辑完成后再打开锁?@TheIrishGuy胡说八道。并发更新会被锁定。并发插入不会相互阻塞。看见