mybatis一级缓存和二级缓存数据脏读问题

Talk is cheap, Show me the code.

void test() {
    /**
     * 一级缓存的作用范围session
     */
    try (SqlSession session = sqlSessionFactory.openSession()) {
      User user = new User();
      user.setId(6);
      user.setName("test6");
      int i = session.insert("addUser", user);

      assertEquals(i, 1);

      /**
       * 本次是从数据库直接读取的,读取之后会存到一级缓存
       *
       * 没有存入二级缓存,二级缓存需要session.commit()之后才会才会真正保存
       * 这也是为什么此处二级缓存没有脏数据的原因
       *
       * 这里数据库的事务隔离级别是读未提交,所以可以读取到六条数据
       */
      List<Object> allUsers = session.selectList("getAllUsers");
      assertEquals(allUsers.size(), 6);

//      session.commit();

      /**
       * 这次是直接从一级缓存读取的数据,属于脏数据
       * 因为session还没有提交,数据随时有可能回滚
       */
      List<Object> allUsers2 = session.selectList("getAllUsers");
      assertEquals(allUsers2.size(), 6);

      session.rollback();
    }

    /**
     * 
     * 二级缓存的作用范围:应用程序启动后的一个namespace
     * 
     * 数据回滚之后,依然只读到五条,说明刚才读取的是脏数据
     */
    try (SqlSession session = sqlSessionFactory.openSession()) {
     List<Object> allUsers = session.selectList("getAllUsers");
      assertEquals(allUsers.size(), 5);
    }

  }

运行日志:

在这里插入图片描述

解决mybatis数据脏读方法:

  1. 彻底关闭一级缓存和二级缓存
  2. 既然使用一级缓存就不能避免脏数据,我们只有记住只有session提交(session.close方法会执行commit操作)之后读到的数据才可以使用,就能避开这个坑。
  3. 如果在分布式系统中二级缓存就可能造成脏数据,我们可以使用redis作为缓存嵌入mybatis,这样就可以解决二级缓存脏读问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值