@Transactional方法中调用saveAndFlush遇RuntimeException,数据会回滚吗?
@Transactional方法中使用saveAndFlush()后回滚的行为分析
答案是肯定的:刷入数据库的变更会在抛出RuntimeException时被还原。
核心原理说明
saveAndFlush()的作用是将当前持久化上下文的变更同步到数据库,但这个同步操作依然处于当前事务的管控范围内。Spring的@Transactional注解默认会对RuntimeException(及子类)触发事务回滚——当方法抛出这类异常时,整个事务会被数据库层面的回滚操作撤销,包括已经通过saveAndFlush()刷入数据库的所有变更。
结合示例代码分析
在你给出的代码中:
@Transactional void foo(){ Order order = orderRepository.fetchById(event.orderId()); order.setBuyer(new Buyer()); orderRepository.saveAndFlush(order); throw new RuntimeException(); }
saveAndFlush(order)执行后,Order的变更会被同步到数据库,但此时事务并未提交;- 后续抛出
RuntimeException,Spring会检测到这个异常并触发事务回滚; - 数据库会撤销之前通过
saveAndFlush()执行的更新操作,最终数据库中的Order记录会回到修改前的状态。
关键注意点
saveAndFlush()不等于事务提交:它只是让数据库提前感知到变更,但这些变更只有在事务成功提交后才会永久生效;- 事务回滚的范围覆盖整个事务内的所有操作:不管是通过
save()延迟同步,还是saveAndFlush()即时同步的变更,只要事务没提交,回滚都会将数据库状态还原到事务开始前。
内容的提问来源于stack exchange,提问作者mihu
相关产品推荐
相关产品推荐

