查阅资料和自己进行测试,得出结论简介:
测试数据库为 postgreSQL,事物隔离级别:读已提交(postgreSQL的默认隔离级别)
- 只读事务内,不能进行增、删、改操作,否则出现异常:cannot execute statement in a read-only transaction;
- 只读事务内,同一个查询方法的多次调用查询结果一致,不会读取到其他事务修改提交后的数据;
- 加只读事务,ORM框架会对其进行查询优化;
下面对结论得出过程和结果进行展示:
测试逻辑:
在一个方法上面添加只读事物注解,方法内部执行两个相同的查询方法和一个和相同SQL语句不同方法名称的方法(一共三次查询)代码见下图↓,第一次查询和第二次查询之间休眠10秒,这段时间内另一个事物执行更新操作(更新查询的该条数据),然后对比查询结果。
一,针对第一条结论得出过程:
1.执行代码:
(图-1)
2.执行结果:
(图-2)
二,针对第二条结论得出过程(有无只读事物注解的情况):
1.执行代码:
(图-3)
2.执行结果(加了只读事物注解的情况):
(图-4)
3.执行结果(没有添加只读事物注解的情况):
(图-5)
1. 只读事务内,同一个查询方法的多次调用查询结果一致,不会读取到其他事务修改提交后的数据:
从SQL日志可以看出第二次查询的时候使用的是第一次查询的缓存结果,并没有查数据库,虽然在第二次查询之前数据库里面的数据已经被改变了,但是他得到的结果还是和第一次查询的一致;注意:这里是相同方法,如果不是相同方法,就如图(图-3)查询代码所示,不同方法,就算是相同SQL语句得到的结果也不一样(因为数据库的隔离级别是“读已提交”,只要其他事物里修改的数据提交了事物,这里就会查询到新的数据)。
如果数据库隔离级别为“可重复读”:在当前事物中,如果不发生修改操作,则在该事物中前后读取到的数据应该是一致的,且不会读取到其他事物中提交或未提交的数据(无论调用哪个查询方法都可以)。
2.加只读事务,ORM框架会对其进行查询优化(没有自己验证究竟是怎么优化的下面是其他文章摘取):
由于只读事务不存在数据的修改,因此数据库将会为只读事务提供一些优化手段,例如Oracle对于只读事务,不启动回滚段,不记录回滚log。