【问题标题】:Rails race condition uniqueness intersection datesRails 比赛条件唯一性交点日期
【发布时间】:2013-02-21 05:22:13
【问题描述】:

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

我正在使用带有活动记录的 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 =&gt; true 而是某种 unique_in_interval =&gt; true

有人能解释一下如何做到这一点吗?

提前致谢。

【问题讨论】:

    标签: ruby-on-rails date unique conditional-statements race-condition


    【解决方案1】:

    只需使用redis locker等任何锁定机制锁定操作

    RedisLocker.new("assign_task_#{@user.id}").run! do
      @user.assign_task(@task) unless @user.has_task_within_time_period?
    end
    

    【讨论】:

      【解决方案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
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-14
        • 2013-11-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-17
        相关资源
        最近更新 更多