MyBatis-Plus多租户插件有时不生效问题

在使用MyBatis-Plus多租户插件时遇到一个问题,同样一个请求查询,有时不会自动拼接租户条件进行查询,可能连续发送几次有一次会是这样,经过对TenantLineInnerInterceptor类的调试跟踪发现了问题所在。

一、问题跟踪

问题就出现在这,在查询之前会进入beforeQuery,在这里InterceptorIgnoreHelper.willIgnoreTenantLine(ms.getId())表示是否会忽略租户条件,如果为true就表示不添加租户条件。

20250227171817668.png

最终进入这个willIgnore函数,如果ignoreStrategy不为空就会进入断点部分代码,导致返回为true,从而忽略多租户条件。

20250227172134167.png

ignoreStrategy是由当前线程变量IGNORE_STRATEGY_LOCAL中获取得到,而设置这个变量的只有handle方法,所以是调用了handle方法导致。

20250227172319453.png

但实质上IGNORE_STRATEGY_LOCAL是一个ThreadLocal对象,应该只在当前线程有效,而且我当前查询并没有调用handle函数,倒是有其它请求有调用这个方法,所以只有一种可能,线程污染导致。

至于两个不同的请求为什么会线程污染,主要跟我项目依赖有关,我使用的spring是采用tomcat作为web服务器,tomcat对请求的处理采用的是线程池的方式,而不是每个请求都建立一个线程,所以如果在A请求中调用了handle方法,但又没清理,它就会一直留在线程当中,当下次某一个请求B进入,tomcat刚好将那个线程分配给这个请求就会出现这种情况。

二、解决方法

解决方法就是在调用handle函数后记得调用clearIgnoreStrategy进行清理。

InterceptorIgnoreHelper.handle(IgnoreStrategy.builder().tenantLine(true).build());  
try {  
    // 业务处理  
} catch (Exception e) {  
    // 清理线程  
    InterceptorIgnoreHelper.clearIgnoreStrategy();  
}

三、问题联想

我这里使用的是spring boot3,默认引入的就是tomcat6,采用的请求线程池是nio形式,在平常的业务中难免会使用ThreadLocal进行业务处理,最好在全局进行清理以防万一:

/**  
 * 全局ThreadLocal清理过滤器  
 * @author 刘靖  
 */  
public class ThreadLocalCleanupFilter implements Filter {  
    @Override  
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {  
        try {  
            // 继续执行请求  
            chain.doFilter(request, response);  
        } finally {  
            // 清理 ThreadLocal 内容  
            cleanupThreadLocal();  
        }  
    }  
  
    /**  
     * 清理 ThreadLocal 中的内容  
     */  
    private void cleanupThreadLocal() {  
        // 这里清除所有 ThreadLocal 中的内容  
        TenantThreadLocal.clear();  
        PermissionThreadLocal.cleanPermission();  
        DataScopeThreadLocal.clean();  
    }  
  
}

但由于tomcat6使用的请求线程池是nio,所以如果在一个请求处理过程中有文件之类的io阻塞操作,线程也可能会切换,所以如果一个请求中既有数据库操作或者是依赖ThreadLocal的操作,尽量把io阻塞的操作放到最后。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容