【问题标题】:implement a booking lock for users in a scheduling app在调度应用程序中为用户实施预订锁定
【发布时间】:2016-05-03 20:25:32
【问题描述】:

我已经构建了一个日程安排网络应用程序,用户可以在其中预订给定日期和该日期时间段的会议。

现在我需要实现一个预订锁,这意味着管理员可以应用这个锁,并且用户从那时起就不能再预订了。

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

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

----------编辑-------------- ----------

这并不是要锁定单个记录(会议)。为此,我使用 user_id 的属性。如果为 0,则会议可以预订。

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

例如:

当用户登录时,他们会看到一条通知说预订已锁定。此外,他们不会看到预订会议的相应按钮,如果他们偶然导航到相应的 URL,他们将被重定向到主页,并显示与上述相同的通知。我已经涵盖了所有这些内容。

但我需要一个通用开关来打开和关闭,并作为这种检查的基础。因此,booking_lock 模型。

注意:我使用的是hanami-model。

----------编辑-------------- ----------

我的问题有两个:

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

【问题讨论】:

  • 您想在应用程序范围内应用锁还是只为特定用户应用锁?
  • 针对特定的用户类别。
  • 抱歉,我不确定我是否理解:特定用户 ID 或特定用户类别?
  • 针对特定的用户类别。具体例子:这是关于家长/教师会议。锁定后,家长无法再预订会议,而教师仍可以为家长预订或取消预订。

标签: sql ruby web-applications hanami


【解决方案1】:

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

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

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

环境变量:

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

数据库持久性

  • 优点:通过多租户架构轻松扩展
  • 缺点:对于一个设置似乎有点矫枉过正,但可以很容易地抽象为多个设置的键/值存储。

示例:

创建一个包含两列的 AppSettings 模型:键和值。

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

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

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

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

【讨论】:

  • 我打算使用 DB 方法,甚至没有想到 ENV 变量的可能性。还有一个问题:您的键/值选项对我的一个值为 On 和 Off 的列有什么好处?
  • 一个好处是下次您需要另一个类似的设置时,您可以在 AppSettings 表中再添加一行。
  • 感谢您的详细解决方案!
  • 我刚刚使用键/值实现了 DB 持久性选项,并且运行良好。
  • 感谢您的反馈!
【解决方案2】:

您可以尝试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)

如果您找回记录,您就成功锁定了它。如果不是,您需要再次尝试使用其他预订,否则在您认领之前它已被抢购一空。

【讨论】:

  • 感谢您的回答。请看我上面的编辑,我之前可能没有详细说明。
猜你喜欢
  • 2016-09-17
  • 2020-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-14
  • 1970-01-01
  • 2023-03-28
相关资源
最近更新 更多