数据库多租户和新线程

时间:2017-08-28 11:47:08

标签: java multithreading spring-boot spring-data-jpa multi-tenant

我使用MultiTenantConnectionProviderCurrentTenantIdentifierResolver

在我的spring-boot应用程序中实现了数据库多租户

我有一个与db连接的静态实例和一个由multitentant连接的动态实例, 一切正常,直到我被迫使用多线程。

New Thread似乎没有关于该动态连接的信息(静态很好),所以我有一个问题,是否有任何可能性将连接信息传递给新线程以便能够使用JPA Repository,因为我可以做通常?

感谢您的回答和建议

3 个答案:

答案 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,并正确访问正确的租户数据库。