在使用弹簧数据存储库之前更改当前模式 - 多租户
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 实现,建立了与预期租户架构的连接。
【讨论】:
以上是关于在使用弹簧数据存储库之前更改当前模式 - 多租户的主要内容,如果未能解决你的问题,请参考以下文章