用于读取的事务可能看起来确实很奇怪,在这种情况下,人们通常不会为事务标记方法.但JDBC无论如何都会创建事务,只是如果没有明确设置不同的选项,它将在autocommit=true
分钟内工作.但将交易标记为只读是有实际原因的:
对数据库的影响
- 只读标志可以让DBMS优化此类事务或并行运行的事务.
- 拥有跨越多个SELECT语句的事务可确保从可重复读取或快照开始的级别得到适当隔离(例如,请参见PostgreSQL's Repeatable Read).否则,如果另一个事务并行提交,两个SELECT语句可能会看到不一致的画面.当使用READ COMMITTED时,这是不相关的.
对ORM的影响
- 如果不明确开始/完成事务,ORM可能会导致不可预测的结果.Hibernate将在第一条语句之前打开事务,但不会完成它.因此,连接将与未完成的事务一起返回到连接池.然后呢?JDBC保持沉默,因此这是特定于实现的:MySQL、PostgreSQL驱动程序回滚此类事务,Oracle提交事务.请注意,这也可以在连接池级别进行配置,例如C3P0为您提供了这样一个选项,默认情况下为回滚.
- Spring在只读事务中设置FlushMode=MANUAL,这会导致其他优化,比如不需要脏判断.这可能会带来巨大的性能提升,具体取决于加载了多少对象.
Impact on architecture & clean code
不能保证您的方法不会写入数据库.如果您将method标记为@Transactional(readonly=true)
,您将决定是否可以在此事务范围内写入DB.如果您的体系 struct 很笨重,并且一些团队成员可能 Select 将修改查询放在不需要的地方,那么这个标志将把您带到有问题的地方.