Spring/Hibernate下的多个会话工厂

Posted

技术标签:

【中文标题】Spring/Hibernate下的多个会话工厂【英文标题】:Multiple Session Factories under Spring/Hibernate 【发布时间】:2010-09-12 07:27:24 【问题描述】:

我被要求在同一个实例中支持多个数据库,以支持多租户。每个数据库都有一个相同的模式。用户通过从列表中选择登录到特定数据库,所有后续调用都将转到该数据库,直到他们注销。

我想根据客户端提供的参数在单个 HibernateDaoTemplate 中热交换会话工厂。

我可以在热交换数据源(以及与之相关的所有事务问题)上找到很多东西,但我想热交换会话工厂 - 为每个工厂保留所有缓存。

最简单的方法是什么?为 DaoTemplate 配置 HotSwappableTarget?谁能指出我如何做到这一点的示例?

【问题讨论】:

【参考方案1】:

如果所有数据库都相同,那么我可以建议使用单个 SessionFactory 并为实际上“租户感知”的 DataSource 和 Cache 提供您自己的实现。 (实现这些是相当简单的:只需维护一张租户 ID 的映射 -> 真实缓存/真实数据源,然后将所有调用委托给适当的调用)。配置单个 SessionFactory 以使用您的租户感知缓存和数据源。 ThreadLocal 可用于使当前请求的租户 ID 可用于任何需要了解它的代码。

我之前成功地使用过这种方法来支持多租户。

【讨论】:

好主意 - 但如何切换租户感知缓存?你所能做的就是配置一个缓存提供者,hibernate 在后台使用它来创建一个缓存。也许实现一个 CacheProvider 来生成租户感知缓存包装器?【参考方案2】:

您还可以查看 Hibernate Shards 项目:

http://www.hibernate.org/414.html

... 专注于向 Hibernate Core 添加对水平分区的支持。它尚未涵盖完整的 Hibernate API,但确实支持其中的大部分(这可能足以满足您的需求,也可能不足以满足您的需求)。当然,他们正在努力实现全面覆盖。

【讨论】:

【参考方案3】:

在我以前工作的地方,我们通过 this guide. 之后的 ThreadLocal 完成了这项工作你有兴趣我可以挖掘更多关于我们实施的信息。

话虽如此,我以前工作场所的人现在正在从这种方法转向分片数据库。绝对是一个更优雅的解决方案,我建议您看看。

【讨论】:

【参考方案4】:

从 HibernateDaoSupport 扩展你的 DAO 类,然后调用 setSessionFactory() 方法,进行数据库的热交换

【讨论】:

【参考方案5】:

我还通过 ThreadLocal 尝试了缓存提供程序,困难的部分是在缓存上进行热交换,您必须确保 SessionFactory 没有任何与之关联的活动会话。现在,我认为有一个更好的解决方案:通过使用 Spring 3 java 配置,您可以动态创建租户感知的 SessionFactory 并让 Spring 为您做缓存管理。

【讨论】:

以上是关于Spring/Hibernate下的多个会话工厂的主要内容,如果未能解决你的问题,请参考以下文章

我可以使用 Spring/Hibernate/c3p0 为多个数据库使用一个池数据源吗?

在 Spring Hibernate 中动态选择数据源 - 方法

Spring + Hibernate:没有为当前线程找到会话

org.hibernate.LazyInitializationException:无法初始化代理 - 没有会话。 Spring + Hibernate + HSQLDB

Spring Hibernate - 无法为当前线程获取事务同步会话

从会话工厂以编程方式获取休眠默认模式名称?