Rails多租户,范围,类变量和线程安全

时间:2011-08-12 13:19:27

标签: ruby-on-rails-3 concurrency thread-safety multi-tenant scopes

短版

类变量在控制器操作期间是否是线程安全的?

长版

我正在编写一个Rails 3应用程序,该应用程序使用单个数据库模式实现多租户,每个表中包含tenant_id列,以标识数据所属的对象。

当然,我需要一种方法来确定在数据库上运行的所有查询的范围,以确保每个租户正确隔离对数据的访问。

有些人建议通过始终通过tenant实例访问数据库来实现这一目标,例如:

current_tenant.associate_collection.where(...)

但是,由于多租户是一个架构问题(不是业务领域关注的问题),我宁愿通过在全局范围内设置范围来尽可能地保持模型的透明度。它也是DRYer。

我发现我可以使用multitenant gem和around_filters:

执行此操作
class ApplicationController
  around_filter do
    Multitenant.with_tenant current_tenant
      yield
    end
  end
end

这会操纵相应模型的default_scope,以便所有数据访问都自动限定为当前租户。

这在开发方面很有用,但我对线程安全性有所顾虑。 Multitenant.with_tenant在类变量中保留current_tenant引用。

问题是当控制器操作在堆栈上时,我可以依赖该变量的完整性吗?还是可能被另一个请求损坏?

另外,Rails中一般并发问题的优秀来源是什么?

1 个答案:

答案 0 :(得分:1)

这不是持续时间问题,并且控制器没有任何特殊之处使它成为原子(不间断)代码序列。线程安全是关于理解锁,同步和线程调度程序。

在这种情况下,我认为你的问题甚至不是Rails特有的。在一般意义上,线程安全是通过在写入时锁定数据来实现的,并在写入完成时解锁它。这是非常相似的数据库锁定机制,如果你熟悉它们。

关于Ruby的一个很好的参考,我会去这里:http://www.rubycentral.com/pickaxe/tut_threads.html

有关线程安全的概念的更多信息(线程在操作系统级别运行,毕竟,它更多的是了解线程安全在任何程序中的工作原理),我会去这里:http://en.wikipedia.org/wiki/Thread_safety