0

I've built a scheduling web app where users can book a conference for a given date and time slot on that date.

Now I need to implement a booking lock, which means that the admin can apply this lock and users can no longer book from that time on.

My current design includes a model booking_lock that only has one attribute of "status" with values of "On" and "Off".

The model would have only one record in the database at any given time as its sole responsibility would be to provide the data to check if booking has been locked.

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

This is not meant to lock individual records (conferences). To do this I use the attribute of user_id. If that is 0, then the conference is available for booking.

What I want to do now is disable (lock) the booking entirely before the user hits the database.

For example:

When a user logs on they see a notification saying the booking is locked. Also, they wouldn't see a respective button to book a conference and if by chance they would navigate to the respective URL they would be redirected to home page with the same notice as above. I've got all this covered.

But I need a general switch to be turned on and off and be the basis for this kind of check. Hence the booking_lock model.

Note: I use hanami-model.

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

My question is twofold:

  1. Is there a better way of implementing such a lock?
  2. How to ensure there is only one record in the db for such lock?
4

2 回答 2

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
于 2016-05-03T12:16:08.633 回答
-1

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

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-05-03T06:05:36.403 回答