• pagehelper 4.x 多线程 bug


    当查询同一sql,在高并发情况下

    或出现 (4.1.x)

    NullPointerException

    或者 

    无法处理该类型[class com.github.pagehelper.sqlsource.PageDynamicSqlSource]的SqlSource



    分析:
    SqlUtils 处
    private Page doProcessPage(Invocation invocation, Page page, Object[] args) throws Throwable {
        ...
        //判断并处理为PageSqlSource
    if (!isPageSqlSource(ms)) {
    processMappedStatement(ms);
    }
        try {
    ...
    //简单的通过total的值来判断是否进行count查询
    if (page.isCount()) {
    page.setCountSignal(Boolean.TRUE);
    //替换MS
    args[0] = msCountMap.get(ms.getId());
    ...
    } else {
    page.setTotal(-1l);
    }
    ...
    } finally {
    ((PageSqlSource)ms.getSqlSource()).removeParser();
    }

    //返回结果
    return page;
    }

    public void processMappedStatement(MappedStatement ms) throws Throwable {
    SqlSource sqlSource = ms.getSqlSource();
    MetaObject msObject = SystemMetaObject.forObject(ms);
    SqlSource pageSqlSource;
    if (sqlSource instanceof StaticSqlSource) {
    pageSqlSource = new PageStaticSqlSource((StaticSqlSource) sqlSource);
    } else if (sqlSource instanceof RawSqlSource) {
    pageSqlSource = new PageRawSqlSource((RawSqlSource) sqlSource);
    } else if (sqlSource instanceof ProviderSqlSource) {
    pageSqlSource = new PageProviderSqlSource((ProviderSqlSource) sqlSource);
    } else if (sqlSource instanceof DynamicSqlSource) {
    pageSqlSource = new PageDynamicSqlSource((DynamicSqlSource) sqlSource);
    } else {
    throw new RuntimeException("无法处理该类型[" + sqlSource.getClass() + "]的SqlSource");
    }
    msObject.setValue("sqlSource", pageSqlSource);
    //由于count查询需要修改返回值,因此这里要创建一个Count查询的MS
    msCountMap.put(ms.getId(), MSUtils.newCountMappedStatement(ms));
    }
     
    1、NullPointerException 分析 
    
      线程1 进入 processMappedStatement 方法,
      将 pageSqlSource 替换 pageSqlSource = new PageDynamicSqlSource((DynamicSqlSource) sqlSource);
      但未执行 msCountMap.put(ms.getId(), MSUtils.newCountMappedStatement(ms));
      线程2进入 isPageSqlSource 方法,判断为true,进入后面的逻辑
      执行 args[0] = msCountMap.get(ms.getId()) ,此时 获取的值为空,则报异常
    
    2、 无法处理该类型[class com.github.pagehelper.sqlsource.PageDynamicSqlSource]的SqlSource 分析
      线程1刚进入 processMappedStatement 方法,此时 sqlSource 的值还未替换   线程2进入 isPageSqlSource 方法,为
    false,进入processMappedStatement 方法,此时线程 1 已经替换sqlSource 则线程2抛出异常
     
  • 相关阅读:
    使用VideoView开发视频总结
    后台接口向数据库录入汉字时乱码以及自动过滤文字经验总结
    8 Crash Reporting Tools For iOS And Android Apps
    Best Mobile Crash Reporting Software
    How do I obtain crash-data from my Android application?
    ACRA (Automated Crash Reporting for Android)
    Debugging Neural Networks with PyTorch and W&B
    OpenPose MobileNet V1
    Real-time-human-pose-estimation-by-pytorch
    openpose-pytorch
  • 原文地址:https://www.cnblogs.com/jaxlove-it/p/13753666.html
Copyright © 2020-2023  润新知