【问题标题】:Rails Convention for Sharing Resources Among Many Users?在许多用户之间共享资源的 Rails 约定?
【发布时间】:2012-06-28 06:49:51
【问题描述】:

在我的应用程序中,我的用户将对患者记录资源执行 CRUD 操作。通常,在创建患者记录后,它只会被用户读取。但是,在极少数情况下,两个(或更多)用户决定出于某种原因想要编辑该共享资源,解决此问题的最佳方法是什么?

我一直在阅读有关乐观和悲观锁定的文章,但我仍然不清楚这是否仅适用于更新操作,还是每次有人尝试读取资源时都会发生锁定?

我在想的是,是否有一种方法可以在 rails 中查看两个或多个用户何时在同一页面上,从而通知第二个用户进入编辑页面另一个用户已经在使用该资源,并且因此,只需等待第一个用户完成后再继续。

你会如何处理这个问题?谢谢!

【问题讨论】:

  • 您没有提及您的数据库,但对于 postgresql:“行级锁不影响数据查询;它们仅阻止同一行的写入者。”
  • 乐观锁和悲观锁都这样吗?
  • 是的。但请注意,读取锁定的记录可能会产生误导,因为用户可能正在读取锁定释放后随后由另一个用户更改的数据。 Postgresql 具有“可重复读取”的概念来防止这种情况发生,但是您将编写纯 sql 来完成此操作,因为我不确定 ActiveRecord 是否支持 postgresql。开发符合并发标准的数据库应用程序并非易事。

标签: ruby-on-rails-3 concurrency locking multi-user


【解决方案1】:

您可以使用acts_as_lockable_by gem 来做到这一点。

按照您问题中的示例:

class Patient < ApplicationRecord
  acts_as_lockable_by :id, ttl: 30.seconds
end

然后您可以在控制器中执行此操作:

class PatientsController < ApplicationController
  def edit
    if patient.lock(current_user.id) 
      # It will be locked for 30 seconds for the current user
      # You will need to renew the lock by calling /patients/:id/renew_lock
    else
      # Could not lock the patient record which means it is already locked by another user
    end
  end

  def renew_lock
    if patient.renew_lock(current_user.id)
      # lock renewed return 200
    else
      # could not renew the lock, it might be already released
    end
  end

  private

  def patient
    @patient ||= Patient.find(params[:id])
  end
end

【讨论】:

    猜你喜欢
    • 2020-07-04
    • 2020-04-14
    • 2018-11-29
    • 2013-12-10
    • 2021-09-24
    • 2011-05-11
    • 2019-10-07
    • 1970-01-01
    相关资源
    最近更新 更多