• 关于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 级别的,这样每次查询结束都会清掉一级缓存






  • 相关阅读:
    elk 之elasticsearch 部分参数参考(1)
    ubuntu16.04安装mariadb 缺少ncurses-devel
    死锁以及避免死锁
    python中的@
    Python中的logging模块
    Cannot find /usr/src/jdk1.7.0_79/lib/*.*/bin/setclasspath.sh 找不到文件
    shelve -- 用来持久化任意的Python对象
    Python-机器学习基础-K近邻算法
    Python-机器学习基础-Pandas
    Java-多线程
  • 原文地址:https://www.cnblogs.com/lwdmaib/p/11050844.html
Copyright © 2020-2023  润新知