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   

 

你可能感兴趣的:(#,事务)