1

在这种情况下,我无法弄清楚如何解决竞争条件。

我正在使用带有活动记录的 rails 3.2.11

我有模型:(只是一个例子)

class Task < ActiveRecord::Base
  belongs_to :person
  attr_accessible :start_date, :end_date, :person_id
end

class Person < ActiveRecord::Base
  has_many :tasks
end

问题是:

我想确保一个人在该时间间隔(start_dateend_date)之间只分配了 1 个任务

例如,

Task | Person_id | start_date       | end_date
0      1           01-01-01 10:00     01-01-01 11:00
1      1           01-01-01 10:15     01-01-01 10:45  ## this should no be valid!!

我知道 Rails 中的验证不会因为竞争条件而阻止这种情况,而且我不能在数据库级别添加索引,因为我不想要,unique => true而是某种unique_in_interval => true

有人可以解释如何做到这一点吗?

提前致谢。

4

2 回答 2

2

只是为了给你一个想法,使用after_create回调来检查在那个条件间隔内刚刚插入的字段的唯一性。

所以在你的任务模型中,

attr_accessor :between_date

after_create :discard_insert


def discard_insert
    @same_records = Person.joins(:tasks).where(:tasks=> {:between_date => start_date..end_date})
end

上述方法将为您提供所有具有竞争条件的记录,然后您可以删除后面的记录。

于 2013-03-06T14:11:30.507 回答
1

只需使用任何锁定机制(如redis locker)锁定操作

RedisLocker.new("assign_task_#{@user.id}").run! do
  @user.assign_task(@task) unless @user.has_task_within_time_period?
end
于 2013-08-15T03:10:57.273 回答