Spring 事物注解@Transactional(readOnly=true)

查阅资料和自己进行测试,得出结论简介:

测试数据库为 postgreSQL,事物隔离级别:读已提交(postgreSQL的默认隔离级别)

  1. 只读事务内,不能进行增、删、改操作,否则出现异常:cannot execute statement in a read-only transaction;
  2. 只读事务内,同一个查询方法的多次调用查询结果一致,不会读取到其他事务修改提交后的数据;
  3. 加只读事务,ORM框架会对其进行查询优化;

下面对结论得出过程和结果进行展示:

测试逻辑:

        在一个方法上面添加只读事物注解,方法内部执行两个相同的查询方法和一个和相同SQL语句不同方法名称的方法(一共三次查询)代码见下图↓,第一次查询和第二次查询之间休眠10秒,这段时间内另一个事物执行更新操作(更新查询的该条数据),然后对比查询结果。

 

一,针对第一条结论得出过程:

1.执行代码:

Spring 事物注解@Transactional(readOnly=true)_第1张图片

                                                                                    (图-1)

2.执行结果:

                                                                                        (图-2)

二,针对第二条结论得出过程(有无只读事物注解的情况):

1.执行代码:

Spring 事物注解@Transactional(readOnly=true)_第2张图片

                                                                                        (图-3)

2.执行结果(加了只读事物注解的情况):

Spring 事物注解@Transactional(readOnly=true)_第3张图片

                                                                                        (图-4)

3.执行结果(没有添加只读事物注解的情况):

Spring 事物注解@Transactional(readOnly=true)_第4张图片

                                                                                        (图-5)

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

       从SQL日志可以看出第二次查询的时候使用的是第一次查询的缓存结果,并没有查数据库,虽然在第二次查询之前数据库里面的数据已经被改变了,但是他得到的结果还是和第一次查询的一致;注意:这里是相同方法,如果不是相同方法,就如图(图-3)查询代码所示,不同方法,就算是相同SQL语句得到的结果也不一样(因为数据库的隔离级别是“读已提交”,只要其他事物里修改的数据提交了事物,这里就会查询到新的数据)。

       如果数据库隔离级别为“可重复读”:在当前事物中,如果不发生修改操作,则在该事物中前后读取到的数据应该是一致的,且不会读取到其他事物中提交或未提交的数据(无论调用哪个查询方法都可以)。

2.加只读事务,ORM框架会对其进行查询优化(没有自己验证究竟是怎么优化的下面是其他文章摘取):

         由于只读事务不存在数据的修改,因此数据库将会为只读事务提供一些优化手段,例如Oracle对于只读事务,不启动回滚段,不记录回滚log。

 

你可能感兴趣的:(SQL优化,数据库,spring,事务)