调用含数据更新操作的存储过程的方法能否使用@Transactional(readOnly = true)
不能用@Transactional(readOnly = true)替代普通的@Transactional注解,原因如下:
@Transactional(readOnly = true)的约束是作用在整个事务上下文的,它不只会拦截应用层面直接执行的INSERT/UPDATE/DELETE语句,还会把对应的JDBC连接标记为只读属性,数据库会直接禁止该事务内的所有写操作,不管这个写操作是应用本身发起的,还是你调用的存储过程内部执行的。- 你调用存储过程的代码为:
这个存储过程内部包含了更新用户状态的写逻辑,放到只读事务里执行大概率会直接触发数据库抛出只读事务不允许修改的异常。ProcedureCall storedProcedureCall = entityManager.unwrap(Session.class).createStoredProcedureCall(StoredProcedures.GET_WEB_APPLICATION_STATE_DATA_AND_UPDATE_USER_STATUS.toString()); - 哪怕部分数据库对只读事务的校验比较宽松,不会直接报错,这种写法也不符合事务语义约定,后续框架、数据库驱动升级很容易出现兼容性问题。
建议直接使用默认的@Transactional注解(默认readOnly = false)修饰该方法即可。
内容的提问来源于stack exchange,提问作者Maurice
相关产品推荐
相关产品推荐

