Mybatis level one, level two cache. Dirty read problem caused by cache


1. Introduction to caching

Mybatis level cache is a SqlSession same scope, perform the same sql statement twice in the same sqlSession, the first complete implementation of
complete database queries will be written into the data cache (memory), and the second will be from the cache The data obtained from it will no longer be queried from the database, thereby improving
query efficiency. When a sqlSession ends, the first level cache in the sqlSession will no longer exist. Mybatis turns on the first level cache by default.
Mybatis second-level cache is shared by multiple SqlSessions, and its scope is the same namespace of the mapper. Different sqlSessions execute
the SQL statement under the same namespace twice and pass the same parameters to the SQL, that is, the same SQL statement is finally executed. After one execution
, the data queried in the database will be written to the cache (memory), and the data will be retrieved from the cache the second time, and the query will no longer be queried from the database, thereby improving query efficiency
. Mybatis does not enable the second-level cache by default. You need to configure the second-level cache in the setting global parameters.
If the second-level cache is not available, look for it from the first-level cache. If the first-level cache is not available, query from the database.


2. Level 1 cache, enabled by default, session level

Clearing the first level cache:

1、关于一级缓存的清空
一级缓存区域是根据SqlSession为单位划分的。
每次查询会先从缓存区域找,
如果找不到从数据库查询,查询
到数据将数据写入缓存。
Mybatis内部存储缓存使用一个HashMap,
Key为hashCode+sqlId+sql语句。value为从查
询出来映射生成的Java对象。
sqlSession执行insert、update、delete等操作commit提交后会清空缓存区域。

Level 1 cache test:

    // 一级缓存默认开启,二级缓存的开启需要配置
    // 一级缓存的作用域:当前session
    @Test
    public void test1() {
    
    
        StuInfoMapper stuMapper = sqlSession.getMapper(StuInfoMapper.class);

        StuInfo stu = stuMapper.getStuInfoById(1);
        System.out.println(stu);

        // 这里是读取的缓存里面的stu
        StuInfo stu1 = stuMapper.getStuInfoById(1);
        System.out.println(stu1);

    }

Query only once


Dirty read problem

Simply put: based on the caching mechanism in mybatis, the result of the query is the result in the cache, and the data is not updated immediately.

    // 缓存带来的脏读问题
    // 这里不开启二级缓存
    @Test
    public void test2() {
    
    

        // 第一个session
        SqlSession sqlSession1 = sqlSessionFactory.openSession();
        StuInfoMapper stuInfoMapper1 = sqlSession1.getMapper(StuInfoMapper.class);
        StuInfo stu1 = stuInfoMapper1.getStuInfoById(1);
        System.out.println(stu1);

        // 第二个session
        SqlSession sqlSession2 = sqlSessionFactory.openSession();
        StuInfoMapper stuInfoMapper2 = sqlSession2.getMapper(StuInfoMapper.class);
        StuInfo stu2 = stuInfoMapper2.getStuInfoById(1);
        System.out.println(stu2);

        // 实现commit 修改操作 清空session1, 重新查询
        stuInfoMapper1.updateStuInfoById(new StuInfo(1, "jack-->小李子",
                null, null, null));

        sqlSession1.commit();

        System.out.println("=============== after update... ================");

        stu1 = stuInfoMapper1.getStuInfoById(1);
        System.out.println("commit session1 重新查询.. " + stu1);

        stu2 = stuInfoMapper2.getStuInfoById(1);
        System.out.println("一级缓存中的stu2, 脏读...  " + stu2);

    }

3. The second level cache, the namespace level of the mapper

Enable caching

Insert picture description here


The current mapper enables secondary cache


test:

    //  二级缓存在所有session之间共享。
    @Test
    public void test1() {
    
    

        // session1
        StuInfoMapper stuInfoMapper1 = sqlSession.getMapper(StuInfoMapper.class);
        StuInfo stu1 = stuInfoMapper1.getStuInfoById(1);

        // session1 关闭, 缓存到二级缓存中
        sqlSession.close();

        System.out.println(stu1);

        // 先读二级缓存,不会查询数据库
        SqlSession sqlSession2 = sqlSessionFactory.openSession();
        StuInfoMapper stuInfoMapper2 = sqlSession2.getMapper(StuInfoMapper.class);
        StuInfo stu2 = stuInfoMapper2.getStuInfoById(1);
        System.out.println(stu2);

    }

Guess you like

Origin blog.csdn.net/qq_44783283/article/details/109747384