Skip to content

Cache pollution possible in multi-tenant mode #3663

@rPraml

Description

@rPraml

We noticed, that our bean chache sometimes contains data of an other tenant.

We use a ThreadLocal for our tenant switching mechanism.

Normally (99.9%) we always make a tenant change in closed blocks (e.g. try-with-resources) and we normally do not pass out any entity of such a block.

small example for better understanding:

ThreadLocal<Integer> currentTenan =...;
currentTenant.set(1); // = ROOT;

try (var ctx = new Context(1000)) { // stores currentTenant value
    // currentTenant == 1000
} // close will restore old value
// currentTenant == 1 (root)
try (var ctx = new Context(2000)) {
        // currentTenant == 2000
        try (var ctx2 = new Context(3000)) { // we support also nesting
                // currentTenant == 3000
        }
        // currentTenant == 2000
}

Unfortunately, there may be 0.1% where we have made a mistake in the code, where an entity is hand out in an other thread. (we did not find that spot, yet) This would be no problem, as long as no lazy load will occur. But there is #914 which guarantees, that the data is queried from the correct database. Unfortunately, the beanCache (tenantAwareKey e.g.) does not honor that value, that was provided for lazy-loading. So when reading from or writing to the beanCache we might hit the wrong cache and either read the wrong data or write the wrong data to the cache

We currently have the following theory:

I think tenant support was added later, so the ThreadLocal approach is no longer completely clean. Especially with the requirement from #914.
In my opinion, we could either prohibit lazy loading from working when the tenant changes, or - other instances are not allowed to rely on the value in CurrentTenantProvider and it must always be passed along during cache accesses.

BTW: If you're making any changes here, I've made the following improvements in the past:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions