返回 Bug 清单
BUG-0143project-41低需关注threadlocal-cleanup

TenantContext ThreadLocal 未清理导致跨请求数据污染

发现:2026-09-30验证:2026-10-09置信度:85%

症状

(静态代码分析推断):请求 A(boothId=100)处理完后线程归还线程池,请求 B 复用同一线程但未设置 boothId,`TenantContext.getBoothId()` 仍返回 100,导致数据查询使用错误的 booth。

根因

`TenantContext` 使用 `ThreadLocal<Long>` 存储 `boothId`: ```java // common-core/src/main/java/com/xianzhi/common/context/TenantContext.java public final class TenantContext { private static final ThreadLocal<Long> currentBoothId = new ThreadLocal<>(); private TenantContext() {} public static void setBoothId(Long boothId) { currentBoothId.set(boothId); } public static Long getBoothId() { return currentBoothId.get(); } public static void clear() { currentBoothId.remove(); } } ``` 虽然 `clear()` 方法已实现,但没有任何 Spring Filter、HandlerInterceptor 或中间件确保在请求结束后(`finally` 或 `afterCompletion`)调用它。当业务异常未走到清理代码时,ThreadLocal 值在线程池中永久残留。

错误签名

`TenantContext` 使用 `ThreadLocal<Long>` 存储 `boothId`:

```java
// common-core/src/main/java/com/xianzhi/common/context/TenantContext.java
public final class TenantContext {
    private static final Thr

技术信息

来源项目

project-41

涉及文件

common-core/src/main/java/com/xianzhi/common/context/TenantContext.java

标签

threadlocal-cleanup, project-41