概念
- 只读事务中,只能有读操作;若增删改会报异常
- 只读事务内,同一个查询方法的多次调用查询结果一致,不会读取到其他事务修改的数据
- 加只读事务,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