zoukankan      html  css  js  c++  java
  • 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抛出异常
     
  • 相关阅读:
    用动画切换按钮的状态
    用UICollectionView实现无限轮播图
    水平方向瀑布流
    UICollectionViewFlowLayout使用示例
    旋转木马效果
    Greenplum集群或者Postgresql出现死锁肿么办?
    Lucene的全文检索学习
    Jms规范学习
    Nginx的相关问题
    keepalived+Nginx实现主备保障Nginx的高可用。
  • 原文地址:https://www.cnblogs.com/jaxlove-it/p/13753666.html
Copyright © 2011-2022 走看看