You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

@Transactional(readOnly = true)的作用是什么?能否用于读写混合操作?

关于@Transactional(readOnly = true)的困惑解答

嘿,太懂这种查了一堆资料还是懵的感觉!来给你把这个点讲透:

先搞懂@Transactional(readOnly = true)到底是干啥的

它本质是个给框架和数据库的提示标记,不是强制禁止写操作的“开关”:

  • 对Spring来说:它会告诉JDBC连接池,这个事务不需要做提交操作,结束时直接释放连接;同时会关闭自动提交(如果是新建事务的话)。
  • 对数据库来说:不同引擎会做不同优化——比如MySQL InnoDB会给只读事务用快照读、跳过写锁,提升查询性能;Oracle则会直接开启严格的只读事务模式,禁止任何DML操作(删、插、改),执行了就报错。

核心问题:能不能在包含读写操作的方法上用?

答案是:绝对不推荐,甚至在某些数据库里会直接失败,结合你的代码例子说:
你的方法里有删除、插入这些写操作,还加了readOnly = true,会出现三种情况:

  1. 如果是新建事务(比如当前没有外层事务,Propagation.REQUIRED会开新事务):
    Spring不会提交这个事务,你的删除、插入操作根本不会生效,数据还是原样。
  2. 如果是加入外层已有的事务:
    写操作会跟着外层事务提交生效,但readOnly = true完全失去了意义——你既拿不到数据库的只读优化,还会误导其他开发者(看到这个注解会以为方法是只读的,后续维护容易出问题)。
  3. 如果是Oracle这类严格执行只读事务的数据库:
    执行删除/插入时直接抛出异常,根本跑不通。

正确用法建议

  • 只有纯查询的方法才加@Transactional(readOnly = true),既能享受数据库的性能优化,又能明确语义,让其他开发者一眼就知道这个方法不会改数据。
  • 包含写操作的方法,要么去掉readOnly属性(默认就是false),要么明确写readOnly = false,别给自己埋坑。

内容的提问来源于stack exchange,提问作者user8710021

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:26:51