zoukankan      html  css  js  c++  java
  • mybatis一级缓存让我憔悴

    Mybatis对缓存提供支持,是默认开启一级缓存。

    来一段代码,这边使用的是mybatis-plus框架,通过构建 QueryWrapper 查询类来实现的。

     1     @Transactional
     2     public ResData assginOrder1(List<SaleAssignData> assignlist) {
     3 
     4         //此处省略很多代码
     5         LocalDateTime now = LocalDateTime.now();
     6         assignlist.stream().forEach(data -> {
     7             Integer projectId = data.getProjectId();
     8             Integer count = data.getCount();
     9             if(count != null && count >0){
    10                 List<OrderDetailDO> list = orderDetailMapper.selectList(new QueryWrapper<OrderDetailDO>()
    11                         .eq("project_id", projectId).eq("agent_id", userId)
    12                         .eq("status",0).orderByAsc("id").last("limit" + count));
    13 
    14                 Integer saleId = data.getUserId();
    15                 SysUserDO saleman = sysUserMapper.selectById(saleId);
    16 
    17                 list.stream().forEach(orderDetailDO ->{
    18                     //此处list处理
    19                 });
    20                 orderDetailService.saveOrUpdateBatch(list);
    21             }
    22         });
    23         
    24         //此处其他表操作
    25         
    26         return new ResData();
    27     }

    如果传入的参数assignlist

    [
        {
            "projectId":1,
            "saleId":1,
            "count":1
        },
        {
             "projectId":1,
             "saleId":2,
             "count":1
        }
    ]

    在同一事务,两次查询条件,projectId和count值一样,原本认为第一次查询出的结果会被修改,可以顺利的修改成功。但事与愿违,两次查询得到的数据结果是一样,两次修改的是同一条数据,这就是因为mybatis一级缓存机制导致。

    那么,怎么解决呢?以下提供两个方法

    方法一:使用随机数方式,在sql处拼接一段随机数  【 .apply(num+"="+num) 】 ,让mybatis认为sql不一样

    Random rn  = new  Random();
    int num = rn.nextInt(100000);
    List<OrderDetailDO> list = orderDetailMapper.selectList(new QueryWrapper<OrderDetailDO>().apply(num+"="+num)
                            .eq("project_id", projectId).eq("agent_id", userId)
                            .eq("status",0).orderByAsc("id").last("limit "+count));

    方法二:springboot配置不使用一级缓存(默认是session级别),但是使用这种情况,一级缓存都不能使用,每次查询都要去数据库查询

    mybatis.configuration.local-cache-scope=statement

    这样就可以得到很好的解决。

  • 相关阅读:
    Assetbundle创建与加载
    11个超棒的iOS开发学习网站
    UGUI
    Unity3D教程宝典之Shader篇
    解决ngui挡住粒子的问题
    unity 随笔
    进程与线程浅析
    c#语言
    Unity3D中使用委托和事件
    Unity3D中常用的数据结构总结与分析
  • 原文地址:https://www.cnblogs.com/Yatces/p/12342481.html
Copyright © 2011-2022 走看看