类变量在控制器操作期间是否是线程安全的?
我正在编写一个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中一般并发问题的优秀来源是什么?
答案 0 :(得分:1)
这不是持续时间问题,并且控制器没有任何特殊之处使它成为原子(不间断)代码序列。线程安全是关于理解锁,同步和线程调度程序。
在这种情况下,我认为你的问题甚至不是Rails特有的。在一般意义上,线程安全是通过在写入时锁定数据来实现的,并在写入完成时解锁它。这是非常相似的数据库锁定机制,如果你熟悉它们。
关于Ruby的一个很好的参考,我会去这里:http://www.rubycentral.com/pickaxe/tut_threads.html
有关线程安全的概念的更多信息(线程在操作系统级别运行,毕竟,它更多的是了解线程安全在任何程序中的工作原理),我会去这里:http://en.wikipedia.org/wiki/Thread_safety