rails – 实现一个简单的锁,以防止用户同时编辑相同的数据

我有一个应用程序,我需要阻止用户在由其他用户编辑数据时编辑数据。 我正在考虑最好的方法,并想要提出想法。 到目前为止,我已经创建了一个设置模型,用于在键/值对中存储db上的应用程序范围配置。 所以,对于锁,我有一个名为LOCKED_TABLE_UID的设置实例,它存储了编辑表的用户的user_id,如果表是空的,则为null(nil)。

>> lock = Setting.find_by_key('LOCKED_TABLE_UID') 

然后,我在我的应用程序控制器中实现了2个方法来获取和释放锁:

 # current_user returns the user currently logged in def acquire_lock lock = Setting.find_by_key("LOCKED_TABLE_UID") if lock.value # if lock taken, see if it's the current_user or someone else if lock.value.to_i == current_user.id.to_i return true else return false end else # lock is free, assign it to this user lock.value = current_user.id return true if lock.save end end def release_lock lock = Setting.find_by_key("LOCKED_TABLE_UID") if lock.value # the lock belongs to current_user, so he can release it if lock.value.to_i == current_user.id.to_i lock.value = nil return true if lock.save else # not your lock, go away return false end else # lock is free, quit bugging return true end end 

我想要的是创建一些包含锁定机制的块代码,如下所示:

 def some_crud_action requires_locking do |lock| if lock # do some CRUD stuff here else # decline CRUD and give some error end end end 

我很感激这方面的帮助 – 但我也对如何完成所有这些,或者我可能忽略的一些事情持开放态度。 这个锁不一定是primefaces的,但是相当基本也是最重要的 – 它有效:)谢谢。

你快到了。 创建require_locking? 你认为合适的行动。 然后使用before_filter处理它。

  before_filter :requires_locking?, :only => [:update, :destroy] after_filter :release_lock, :only => [:update, :destroy] def requires_locking do |lock| unless acquire_lock lock = Setting.find_by_key("LOCKED_TABLE_UID") user_with_lock = User.find(lock.value) flash[:message] = "Action denied: Table locked by: #{user_with_lock.name}" redirect_to :back end end 

您是否看过ActiveRecord内置锁定function?

  • 乐观锁定
  • 悲观锁定

我喜欢这个想法,但看到你的解决方案存在一个大问题,那就是你正在获取并释放整个表的锁。

对于一个可能很好的非常小的应用程序,但想象一下,如果有成千上万的用户试图访问,例如,“产品”表,并且必须等待,因为有人正在编辑与他们自己的产品完全无关的条目。

也许你可以采用更精细的颗粒方法并锁定特定的行而不是表格。 然后锁将包括表名,行ID和用户ID。

我认为acts_as_lockable_by gem正是以更简单的术语和更少的代码完成你所要求的。 它很容易与rails甚至是一个裸ruby项目集成。

使用此gem,您将获得primefaceslockunlockrenew_lock方法。 此外,你得到一个自动过期的ttl锁,所以如果狗屎击中风扇,你无法解锁资源,它将自动解锁为你!