关于mybatis 一级缓存引发的问题

场景: 由于在一个方法中存在多个不同业务操作   

  private void insertOrUpdateField(CompanyReport entity) {
      

                //计算并数据
            calcReportData(entity);

            // 对比上季度或上年度数据,生成风险警示
            raiseReportRisk(entity.getId());

            // 检测并级联产生年度数据,并对比年度数据,生成风险警示
            checkAndGenerateYearData(entity.getId());

  }

 private void raiseReportRisk(String reportId){
        CompanyReport report = get(reportId);
        //产生问题的地方---------------------------
        //若为季度数据,则找上一季度
        if(report.getYear() != null && report.getQuarter() != null){
            if(report.getQuarter() >1){
                report.setQuarter(report.getQuarter() - 1);
            } else{
                report.setYear(report.getYear() - 1);
                report.setQuarter(4);
            }


        } else {
            //若为年度数据,则找上一年度
            report.setYear(report.getYear() - 1);
        }
        CompanyReport lastReport = getByPeriod(report);
        if(lastReport != null){
            //重置风险状态
            fieldValueMapper.updateForResetRisk(reportId);
            //识别风险状态
            fieldValueMapper.updateForRisk(reportId, lastReport.getId());
        }


    }
private void checkAndGenerateYearData(String reportId){

        CompanyReport currentReport = get(reportId);
    
          //这里的year  quarter两个值与数据库里不一致了
    }

        

由于上面一段代码的执行顺序问题  

1:生成风险警示raiseReportRisk 执行这个方法的时候  通过id查询了companyReport对象  那么这时候mybatis会将数据存储在一级缓存中   
同时将查询结果companyReposrt 中的year 与quarter修改了
2:在级联产生年度数据的时候checkAndGenerateYearData 又通过id去查询companyReport 由于第一次已经查询过了 第二次又进行了一次查询 第二次默认查询了是缓存中的数据
那么结果就是year 被修改的数据 造成了严重的不一致问题

解决方案:1:调整两个方法的执行顺序 在业务允许的情况下
2:将raiseReportRisk 中查询的companyReposrt 重新创建一个新的对象 将属性赋值过去 两个对象 修改重新创建的对象
3: 每次查询都更新查询缓存 mybatis一级缓存如何修改
一级缓存的级别设为 statement 级别的,这样每次查询结束都会清掉一级缓存






原文地址:https://www.cnblogs.com/lwdmaib/p/11050844.html