相关疑难解决方法(0)

如何在Rails应用程序中避免竞争条件?

我有一个非常简单的Rails应用程序,允许用户在一组课程中注册他们的出勤.ActiveRecord模型如下:

class Course < ActiveRecord::Base
  has_many :scheduled_runs
  ...
end

class ScheduledRun < ActiveRecord::Base
  belongs_to :course
  has_many :attendances
  has_many :attendees, :through => :attendances
  ...
end

class Attendance < ActiveRecord::Base
  belongs_to :user
  belongs_to :scheduled_run, :counter_cache => true
  ...
end

class User < ActiveRecord::Base
  has_many :attendances
  has_many :registered_courses, :through => :attendances, :source => :scheduled_run
end
Run Code Online (Sandbox Code Playgroud)

ScheduledRun实例具有有限数量的可用位置,一旦达到限制,就不能再接受更多的考勤.

def full?
  attendances_count == capacity
end
Run Code Online (Sandbox Code Playgroud)

attendances_count是一个计数器缓存列,包含为特定ScheduledRun记录创建的出勤关联数.

我的问题是,当一个或多个人同时尝试在课程中注册最后一个可用位置时,我不完全知道确保不会发生竞争条件的正确方法.

我的考勤控制器如下所示:

class AttendancesController < ApplicationController
  before_filter :load_scheduled_run
  before_filter :load_user, :only => :create

  def new
    @user = User.new
  end

  def …
Run Code Online (Sandbox Code Playgroud)

database activerecord ruby-on-rails optimistic-locking

20
推荐指数
1
解决办法
7617
查看次数

使用Sidekiq的并发性导致了一些问题

我在我的rails应用程序中使用Sidekiq一次排队50k +作业.我们的游泳池大小设置为9.

工作都是相关的,并做同样的事情.我们有另一个模型,它有一个计数器.在每个作业期间,我们检查该模型是否具有值大于200的列.如果它大于200,我们创建该模型的另一个实例,其值为0并继续作业.但是,由于我们一次运行9个作业,因此所有9个作业同时读取该列的值大于200,并且所有作业都创建新实例,这是不正确的.

解决这个问题的最佳方法是什么?我们基本上希望所有工作都能从最新的价值中读取.

ruby-on-rails sidekiq

8
推荐指数
1
解决办法
581
查看次数