Spring事务细节【只读设置】:readOnly

概念

 

  1. 只读事务中,只能有读操作;若增删改会报异常
  2. 只读事务内,同一个查询方法的多次调用查询结果一致,不会读取到其他事务修改的数据
  3. 加只读事务,ORM框架会对其进行查询优化

参考:https://www.pianshen.com/article/2061695048/

测试代码

1. 验证:只读事务只能有读操作

@Service
public class TestNumService {
    @Autowired
    private TestAMapper testAMapper;

    @Transactional(readOnly = true)
    public void queryNum(){
        testAMapper.addNumA();
    }
}
报错:
### Error updating database.  Cause: java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed

2. 验证:只读事务内,同一个查询方法的多次调用查询结果一致,不会读取到其他事务修改的数据


@Service
public class TestNumService {
    @Autowired
    private TestAMapper testAMapper;
    @Autowired
    private TestBMapper testBMapper;

    @Transactional()
    public void changeNum(){
        System.out.println("addNumA开始");
        testAMapper.addNumA();
        System.out.println("addNumA结束");
        System.out.println("addNumB开始");
        testBMapper.descNumB();
        System.out.println("descNumB结束");
    }
    @Transactional(readOnly = true)
    public String queryNum(){
        //
        testA a1 = testAMapper.queryA();
        System.out.println("a1="+a1.getA());
        //该休眠时间用于changeNum修改数据
        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        testA a2 = testAMapper.queryA();
        System.out.println("a2="+a2.getA());

        return JSON.toJSONString("a1="+a1.getA()+",a2="+a2.getA());
    }
}
执行顺序:queryNum -- > 读取a1完成 --> changeNum
a1=10
addNumA开始
addNumA结束
addNumB开始
descNumB结束
a2=10     # mybatis缓存

3. 验证事务原子性

@Transactional()
public void changeNum(){
    System.out.println("addNumA开始");
    testAMapper.addNumA();
    System.out.println("addNumA结束");
    System.out.println("addNumB开始");
    testBMapper.descNumB();
    System.out.println("descNumB结束");
}
@Transactional(readOnly = true)
public String queryNum(){
    //
    testA a1 = testAMapper.queryA();
    System.out.println("a1="+a1.getA());
    try {
        Thread.sleep(4000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    //
    testB b = testBMapper.queryB();
    System.out.println("b="+b.getB());

    return JSON.toJSONString("a1="+a1.getA()+",b="+b.getB());
}
执行顺序:queryNum -- > 读取a1完成 --> changeNum 
a1=10
addNumA开始
addNumA结束
addNumB开始
descNumB结束
a2=10
再次queryNum: 
a1=11
b=9   

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值