Hibernate/Spring事务执行顺序异常:如何保证nextId先于存储过程调用?
保证原生查询与存储过程的执行顺序解决方案
方案一:为原生查询添加Flush Mode提示
在nextId()方法上通过@QueryHint设置Hibernate的FlushMode为ALWAYS,强制Hibernate在执行该查询前立即处理会话中的所有挂起操作,并立即执行当前查询,避免延迟执行导致顺序错乱。
修改后的Repository代码:
@Repository public interface MyRepository extends JpaRepository<MyRepoEntity, Long> { @Query(value="SELECT NEXTVAL('mytable')", nativeQuery=true, hints = { @QueryHint(name = org.hibernate.annotations.QueryHints.FLUSH_MODE, value = "ALWAYS") }) Long nextId(); @Procedure(procedureName = "SCHEMA2.save_2", outputParameterName = "res") String callProcedure(@Param("prm_nrid") Long nr); }
方案二:将序列查询放在独立事务中
通过事务传播特性REQUIRES_NEW,让序列查询在独立的事务中执行,确保该操作完全完成后再执行存储过程调用。
修改业务管理器代码:
@Transactional String invokeProcedure1() { Long id = getNextIdInNewTransaction(); return myRepo.callProcedure(id); } @Transactional(propagation = Propagation.REQUIRES_NEW) Long getNextIdInNewTransaction() { return myRepo.nextId(); }
方案三:直接使用EntityManager执行序列查询
绕过Spring Data JPA的方法封装,直接通过EntityManager创建原生查询并立即执行,强制查询顺序。
修改业务管理器代码:
@Autowired private EntityManager em; @Autowired private MyRepository myRepo; @Transactional String invokeProcedure1() { Query query = em.createNativeQuery("SELECT NEXTVAL('mytable')"); Long id = (Long) query.getSingleResult(); return myRepo.callProcedure(id); }
以上方案均无需显式调用flush()即可保证nextId()在callProcedure()之前执行。
内容的提问来源于stack exchange,提问作者user5822650
相关产品推荐
相关产品推荐

