在使用弹簧数据存储库之前更改当前模式 - 多租户

Posted

技术标签:

【中文标题】在使用弹簧数据存储库之前更改当前模式 - 多租户【英文标题】:Change current schema before using spring data Repository - Multi tenancy 【发布时间】:2021-01-28 02:30:19 【问题描述】:

我正在使用一个多租户 Spring Boot Web 应用程序,它从数据库中读取一些数据。

我为每个租户模型构建了架构,实现了 MultiTenantConnectionProvider 和 CurrentTenantIdentifierResolver 以根据租户设置连接。租户使用 ThreadLocal 变量解析,该变量设置在 Filter 中(通过扩展 OncePerRequestFilter 构建)。

但是,我需要解决在过滤器中无法获取租户信息的特定情况。但是,我可以稍后在处理服务中的请求时获取租户信息,但是此时实体管理器已设置(似乎由 OpenSessionInViewFilter 查看 spring 源代码完成)以使用默认模式,并且我的所有查询都失败了,因为默认架构不包含我需要的数据。

我的问题是,在休眠过滤器已经设置会话之后,如何将实体管理器设置为指向服务级别的租户特定架构?我可以做任何过滤器(OpenSessionInViewFilter)正在做的事情,如下所示:

   EntityManager entityManager = entityManagerFactory.createEntityManager();
   TransactionSynchronizationManager.bindResource(entityManager, new EntityManagerHolder(entityManager));
   //unbind once I am done using the repositories

但我在想这是否是正确的方法,或者是否有任何其他更好、更简单、记录在案的方法。

【问题讨论】:

【参考方案1】:
   EntityManager entityManager = entityManagerFactory.createEntityManager();
   TransactionSynchronizationManager.bindResource(entityManager, new 
   EntityManagerHolder(entityManager));

以上对我不起作用。但是,我找到了一种解决方法——通过在不同的线程中运行我的任务(我刚刚创建了一个固定线程池执行程序并提交了我的任务)并将新租户设置在 ThreadLocal 对象中,我能够实现我想要的。通过正确的 CurrentTenantIdentifierResolver 和 MultiTenantConnectionProvider 实现,建立了与预期租户架构的连接。

【讨论】:

以上是关于在使用弹簧数据存储库之前更改当前模式 - 多租户的主要内容,如果未能解决你的问题,请参考以下文章

存储库和工作单元模式 - 如何保存更改

配置文件的弹簧云配置模式匹配

处理存储库方法的弹簧方式[重复]

使用 Atlassian Sourcetree,是不是可以在执行拉取之前查看将从远程存储库中拉取哪些更改?

初始孵化后如何更改用户数

将存储库模式与文档数据库一起使用是不是有意义?