Mybatis-Plus租户id结合定时任务 @Scheduled 注解使用坑

Mybatis-Plus租户id结合定时任务 @Scheduled 注解使用踩的坑

因为业务需求需要加定时任务,所以图方便直接使用了@Scheduled 注解加Cron表达式进行每30分钟跑一次定时任务,但是运行的时候突然发现报了个No thread-bound request found: Are you referring to request attributes outside of an actual web request
也就是定时任务拿不到request请求

详细日志

2022/12/02-15:22:00 ERROR [pool-1-thread-1] org.springframework.scheduling.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task.
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
### The error may exist in file [F:\workspace\project\target\classes\mapper_xml\xxxxMapper.xml]
### The error may involve com.jsh.erp.datasource.mappers.ApplicantMapper.selectApplicantInterviewTime
### The error occurred while executing a query
### Cause: java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.

解决方案

一、技术有问题,@Scheduled 注解定时任务不可能拿到HttpServletRequest请求, 直接改变技术架构
二、配置mybatis-plus Config类,过滤表,将定时任务需走数据库的表通通过滤,不使用租户id
@Bean
    public PaginationInterceptor paginationInterceptor(HttpServletRequest request) {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        List<ISqlParser> sqlParserList = new ArrayList<>();
        TenantSqlParser tenantSqlParser = new TenantSqlParser();
        tenantSqlParser.setTenantHandler(new TenantHandler() {
            @Override
            public Expression getTenantId() {
                String token = request.getHeader("X-Access-Token");
                Long tenantId = Tools.getTenantIdByToken(token);
                if (tenantId != 0L) {
                    return new LongValue(tenantId);
                } else {
                    //超管
                    return null;
                }
            }

            @Override
            public String getTenantIdColumn() {
                return "tenant_id";
            }

            @Override
            public boolean doTableFilter(String tableName) {
                if ("t_xxxx".equals(tableName)) {//你要过滤的表名
                   return true;
                }
                
        });

        
    }

你可能感兴趣的:(mybatis,java,spring)