@Transactional(readOnly = true)的作用是什么?能否用于读写混合操作?
关于@Transactional(readOnly = true)的困惑解答
嘿,太懂这种查了一堆资料还是懵的感觉!来给你把这个点讲透:
先搞懂@Transactional(readOnly = true)到底是干啥的
它本质是个给框架和数据库的提示标记,不是强制禁止写操作的“开关”:
- 对Spring来说:它会告诉JDBC连接池,这个事务不需要做提交操作,结束时直接释放连接;同时会关闭自动提交(如果是新建事务的话)。
- 对数据库来说:不同引擎会做不同优化——比如MySQL InnoDB会给只读事务用快照读、跳过写锁,提升查询性能;Oracle则会直接开启严格的只读事务模式,禁止任何DML操作(删、插、改),执行了就报错。
核心问题:能不能在包含读写操作的方法上用?
答案是:绝对不推荐,甚至在某些数据库里会直接失败,结合你的代码例子说:
你的方法里有删除、插入这些写操作,还加了readOnly = true,会出现三种情况:
- 如果是新建事务(比如当前没有外层事务,Propagation.REQUIRED会开新事务):
Spring不会提交这个事务,你的删除、插入操作根本不会生效,数据还是原样。 - 如果是加入外层已有的事务:
写操作会跟着外层事务提交生效,但readOnly = true完全失去了意义——你既拿不到数据库的只读优化,还会误导其他开发者(看到这个注解会以为方法是只读的,后续维护容易出问题)。 - 如果是Oracle这类严格执行只读事务的数据库:
执行删除/插入时直接抛出异常,根本跑不通。
正确用法建议
- 只有纯查询的方法才加
@Transactional(readOnly = true),既能享受数据库的性能优化,又能明确语义,让其他开发者一眼就知道这个方法不会改数据。 - 包含写操作的方法,要么去掉
readOnly属性(默认就是false),要么明确写readOnly = false,别给自己埋坑。
内容的提问来源于stack exchange,提问作者user8710021
相关产品推荐
相关产品推荐

