我使用MultiTenantConnectionProvider
和CurrentTenantIdentifierResolver
我有一个与db连接的静态实例和一个由multitentant连接的动态实例, 一切正常,直到我被迫使用多线程。
New Thread似乎没有关于该动态连接的信息(静态很好),所以我有一个问题,是否有任何可能性将连接信息传递给新线程以便能够使用JPA Repository,因为我可以做通常?
感谢您的回答和建议
答案 0 :(得分:0)
请使用TenantContext,如此处所述 - https://dzone.com/articles/spring-boot-hibernate-multitenancy-implementation
每次调用新线程时,请确保重置上下文,因为新线程将丢失当前租户的标识符信息。
答案 1 :(得分:0)
将请求中的租户ID /信息作为URL的一部分或在Header中传递,并使用过滤器通过租户持有者/上下文将其设置为ThreadLocal。
我在Multi-tenant applications using Spring Boot, JPA, Hibernate and Postgres
上写了这篇博文我将很快发布关于如何通过TenantStore传递租户数据的博客,以防止直接搞乱ThreadLocal并支持在服务,资源中注入TenantStore ......
答案 2 :(得分:0)
我们需要的是将 租户ID 从当前线程传递到新创建的线程,以在多租户模式下工作。为此,我们必须维护TenantContext如下:
public class TenantContext {
private static final ThreadLocal<Tenant> tenantHolder = new ThreadLocal<>();
public static Tenant getTenant() {
Tenant tenant = tenantHolder.get();
return Objects.isNull(tenant) ? Tenant.DEFAULT : tenant;
}
public static void setTenant(Tenant tenant) {
tenantHolder.set(tenant);
}
public static void clearTenant() {
tenantHolder.remove();
}
}
租户是包含所有租户ID的枚举。当我们在创建新线程之前首先解决租户时,必须将其设置为 TenantContext 。
现在,我们必须编写新的自定义线程类。
public class TenantAwareThread extends Thread {
private Tenant tenant = null;
public TenantAwareThread(Runnable target) {
super(target);
this.tenant = TenantContext.getTenant();
}
@Override
public void run() {
TenantContext.setTenant(this.tenant);
super.run();
TenantContext.clearTenant();
}
}
最后,我们可以如下创建线程:
new TenantAwareThread(() -> {
//do operation
}).start();
新线程将自动获得租户ID,并正确访问正确的租户数据库。