在计划应用程序中为用户实施预订锁定

时间:2016-05-03 05:39:03

标签: sql ruby web-applications hanami

我已经构建了一个计划网络应用程序,用户可以在该日期和时间段预订会议。

现在我需要实施预订锁定,这意味着管理员可以应用此锁定,用户无法再预订。

我目前的设计包括一个型号booking_lock,它只有一个属性为“status”且值为“On”和“Off”。

在任何给定时间,模型在数据库中只有一条记录,因为它的唯一责任是提供数据以检查预订是否已被锁定。

--------------------- EDIT ------------------------- ----------

这并不意味着锁定个人记录(会议)。为此,我使用user_id的属性。如果是0,那么会议可以预订。

我现在要做的是在用户点击数据库之前完全禁用(锁定)预订。

例如:

当用户登录时,他们会看到一条通知,说明预订已被锁定。此外,他们不会看到相应的按钮来预订会议,如果他们偶然会导航到相应的URL,他们将被重定向到主页,具有与上述相同的通知。我已经完成了这一切。

但我需要打开和关闭一般开关,并作为此类检查的基础。因此,booking_lock模型。

注意:我使用hanami-model。

--------------------- EDIT ------------------------- ----------

我的问题有两个:

  1. 有没有更好的方法来实现这样的锁?
  2. 如何确保数据库中只有一条记录用于此类锁定?

2 个答案:

答案 0 :(得分:1)

1。有没有更好的方法来实现这样的锁?

您的要求似乎是应用程序范围的设置,最好用

完成
  • 环境变量
  • 存储在数据库中的值

环境变量:

  • 专业:系统已经到位,使用简单,可以轻松静态配置并动态更改
  • 缺点:使用多租户架构(运行相同应用程序的多台服务器)可能难以维护

数据库持久性

  • 专业人士:使用多租户架构轻松扩展
  • 缺点:对于一个设置来说看起来有点过分但是可以很容易地将其抽象到用于多个设置的键/值存储中。

实施例

创建一个包含两列的AppSettings模型:key&值。

使用键" lock_booking_for_parents"创建并保存AppSetting。并通过管理界面更改该值。

在整个应用中访问此AppSet,以了解您是否应该锁定预订。

此外,如果您每次需要知道是否启用了预订时都担心查询数据库,则可以轻松实现缓存。

2。如何确保数据库中只有一条记录用于此类锁定?

环境变量

不适用

数据库持久性

您可以创建一个帮助程序类来使用默认行为访问您的设置,并使用first_or_create方法确保记录是唯一的。

class AppSettingsHelper

    def self.booking_enable?
      app_setting_record = AppSettings.find_by_key("lock_booking_for_parents")
      if app_setting_record 
        return app_setting_record.value
      else 
        ## default behavior of your app when no record has been created yet
        return true
      end
    end

    def self.enable_booking
      AppSettings.where(:key => "lock_booking_for_parents").first_or_create({value: false})
    end

    def self.disable_booking
      AppSettings.where(:key => "lock_booking_for_parents").first_or_create({value: true})
    end  
end

答案 1 :(得分:-1)

您可以尝试使用ActiveRecord pessimistic locking方法,或类似的方法。在记录上设置一个表示锁定的字段并尝试:

booking_lock = UUID.new # Or any sufficiently unique string
Booking.update_all({ id: @booking.id, booking_lock: booking_lock }, { booking_lock: nil })
booked = Booking.find_by(id: @booking.id, booking_lock: booking_lock)

如果你收到记录,你就成功锁定了它。如果不是,你需要再次尝试使用不同的预订,它会在您声明之前被抓住。