我有一个非常简单的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) 我在我的rails应用程序中使用Sidekiq一次排队50k +作业.我们的游泳池大小设置为9.
工作都是相关的,并做同样的事情.我们有另一个模型,它有一个计数器.在每个作业期间,我们检查该模型是否具有值大于200的列.如果它大于200,我们创建该模型的另一个实例,其值为0并继续作业.但是,由于我们一次运行9个作业,因此所有9个作业同时读取该列的值大于200,并且所有作业都创建新实例,这是不正确的.
解决这个问题的最佳方法是什么?我们基本上希望所有工作都能从最新的价值中读取.