【那些码那些事】readOnly执行是否报错

答案不一定,和配置有关。
普通事务查询事务应该都会这么去配置


为什么有的码友自信满满的说他配置了readOnly = true ,但是在方法里面执行了缺是正常的,无报错行为?经过本人的测试,也出现了无报错正常执行的过程,但是是有前提的。我们假设查询方法为queryUserById(Long id),保存的方法为saveUser(User user)。

  1. 直接调用查询 queryUserById(Long id),能够正常查询并返回所需要的信息;如果将方法体修改为inser语句,也可以正常插入用户信息,并不会报错。这是因为 SUPPORTS 的传播行为是,如果有事务就是用事务如果没有事务就不是用事务。显而易见,这种调用方法并没有开启事务也就不存在事务的readOnly属性了。
  2. 调用saveUser(User user)方法,方法内部调用queryUserById(Long id);这时候如果queryUserById(Long id)方法体修改为inser语句,则依然不会报错。原因是由于事务传播机制造成的,queryUserById所使用的事务不是自己的,而是由saveUser()创建的事务继承过来的,saveUser()的事务readOnly默认是false,也因此不会报错。
为什么有的人说报错,有的人说不可以呢?

场景1:
我们将其中一个配置信息修改为 然后你再试试?日志上会有一段预期的error:

readOnly操作异常日志.png

场景2:
我们将其中一个配置信息修改为
同样会出现以上问题,但这是保存事务啊,read个毛线的only啊,你是不是傻?

小结

关于readOnly的解释,官方文档说明如下:


readOnly属性注释.png

意思如下(来自某度的翻译):
如果事务是有效只读的,则可以将其设置为真的布尔标记,允许在运行时进行相应的优化。默认值为假。这只是对实际事务子系统的提示;它不一定会导致写入访问尝试失败。无法解释只读提示的事务管理器在请求只读事务时不会引发异常,而是静默地忽略该提示。

另:本人的实验环境为 spring4.x + mybatis + mysql。不知道不同的环境会不会出现不同的现象,网上码友有在hibernate说报错,这个鄙人木有实验过。

至此为止,懂了?

你可能感兴趣的:(【那些码那些事】readOnly执行是否报错)