spring事物隔离级别和mybatis缓存的问题

今天使用@Transactional遇到了问题,通过一些实验,总结下自己的想法。如有不当欢迎指正~

项目使用spring boot + mybatis + mysql,先上代码:

    @Override
    @Transactional
    public void test(){
        UDeptDO dept = uDeptDao.get("0cf58a5d6ae811e89feafa163eb3e537");
        // 打印旧值
        log.info("deptname={}", dept.getDeptname());
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
        }
        dept.setDeptname("test");
        update(dept);
        dept = uDeptDao.get("0cf58a5d6ae811e89feafa163eb3e537");
        // 打印新值
        log.info("deptname={}", dept.getDeptname());
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
        }
    }
    
    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public void test1(){  
        UDeptDO dept = uDeptDao.get("0cf58a5d6ae811e89feafa163eb3e537");
        // 打印旧值
        log.info("deptname={}", dept.getDeptname());
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
        }
        // 打印旧值,事物未提交
        dept = uDeptDao.get("0cf58a5d6ae811e89feafa163eb3e537");
        log.info("deptname={}", dept.getDeptname());
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
        }
        // 打印新值,事物已提交,READ_COMMITTED生效
        dept = uDeptDao.get("0cf58a5d6ae811e89feafa163eb3e537");
        log.info("deptname={}", dept.getDeptname());
    }

以上是一个service实现类的两个测试方法,方法test使用Spring事物的默认隔离级别(也就是由底层数据库提供的隔离级别,mysql默认是REPEATABLE_READ),方法test1使用READ_COMMITTED。同时调用test和test1,预期test1方法第三次查询能获取到修改值,但是并没有成功(此处纠结了好久,还以为自己理解错了。。。)。分析日志发现test1后两次查询未打印SQL语句,估计是缓存的原因。给mapper文件的查询语句加上useCache="false" flushCache="true"这两个配置,问题解决。


从这个例子可以看到,READ_COMMITTED可以避免dirty reads,即test1第二次查询不会查到test的修改,只有test方法事物提交后,test1在第三次查询才能看到。这里test1方法后两次的查询行为,其实就是我们常说的non-repeatable reads。如果使用REPEATABLE_READ级别,能使test1的三次查询结果保持一致。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值