spring-projects / spring-data-examples

Spring Data Example Projects
Apache License 2.0
5.17k stars 3.39k forks source link

Unsafe tenant identifier for concurrent requests in jpa multitenancy example #686

Closed TamimEhsan closed 1 month ago

TamimEhsan commented 1 month ago

The currentTenant value in the TenantIdentifierResolver.java file is not thread-safe, which can lead to issues in a multi-threaded environment where concurrent requests are handled.

Problem:
The currentTenant variable is shared across multiple threads, which can cause race conditions and inconsistent behavior when multiple requests are processed concurrently.

https://github.com/spring-projects/spring-data-examples/blob/9988a78cba853a3f5ea08b8501a933f4f8c3d065/jpa/multitenant/schema/src/main/java/example/springdata/jpa/hibernatemultitenant/schema/TenantIdentifierResolver.java#L28-L37

Steps to Reproduce:
Deploy the application in a multi-threaded environment. Send multiple concurrent requests that rely on the currentTenant value.

Expected Result: Each request should have its own isolated currentTenant value.

Actual Result:
The currentTenant value is shared across threads, leading to potential data corruption and inconsistent behavior.

Suggested Fix:
Consider using a ThreadLocal variable to store the currentTenant value for each thread independently. This will ensure that each request has its own isolated currentTenant value.

Example:

private static final ThreadLocal<String> currentTenant = ThreadLocal.withInitial(() -> "public");

public void setCurrentTenant(String tenant) {
    currentTenant.set(tenant);
}

public String getCurrentTenant() {
    return currentTenant.get();
}
schauder commented 1 month ago

This is purely an example how to integrate Hibernate multi tenancy features with Spring Data JPA. I assumed it would be obvious that for a real application one needs do decide on the appropriate scope of the currentTenant. I'll add a comment to that effect to the readme.