Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Database multitenancy and new thread

I've implemented database multitenancy in my spring-boot application using MultiTenantConnectionProvider and CurrentTenantIdentifierResolver

I have one static instance of connection to db and one dynamic by multitentant, everything worked fine until I get forced to use multithreating.

New Thread seems to loose information about that dynamic connection (the static is fine), so I have a question, is there any posibility to pass the connection information to the new thread to be able use JPA Repository, as I can do normally?

Thanks for answers and advises

like image 941
rdabrowski Avatar asked Jun 13 '26 09:06

rdabrowski


2 Answers

What we need is to pass tenant id from current thread to newly created thread to work in multi tenancy mode. For this, we have to maintain TenantContext as follows:

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();
    }
}

Tenant is the enum which holds all Tenant Ids. When we first resolve tenant before creating new thread, we have to set it to TenantContext.

Now, we have to write new custom thread class.

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();
    }
}

Finally, we can create thread as follows:

new TenantAwareThread(() -> {
    //do operation
}).start();

New thread will get tenant ID automatically and properly access the right tenant's database.

like image 158
arifng Avatar answered Jun 15 '26 21:06

arifng


Please use a TenantContext as explained here - https://dzone.com/articles/spring-boot-hibernate-multitenancy-implementation

Every time a new thread is invoked, make sure the context is reset because a new thread would lose the current tenant's identifier information.

like image 45
Righto Avatar answered Jun 15 '26 22:06

Righto