【问题标题】:Does Spring @Transactional annotated on method ensure the flush of data exactly when the method ends?Spring @Transactional 注解的方法是否确保在方法结束时准确刷新数据?
【发布时间】:2019-10-02 18:50:52
【问题描述】:

我在一个带有 Java 和 Hibernate 的 Spring 应用程序中为持久性提供程序提供了这个简化的场景:

@Transactional
void method1() { // some savings}

@Transactional
void method2() { // some savings}

当我运行父方法时(未注释为事务性)

void parentMethod() {
    method1();
    method2();
}

我能否确保在方法完成时,在调用该方法之前,数据库中的更改立即受到影响? 或者更改可能会在稍后刷新到数据库,但会有一些延迟?

我对其他应用程序感兴趣,它会在方法 1 完成时(以及在调用方法 2 之前)立即看到数据库中所做的更改

更新 我的父方法没有定义在同一个类中,并且我的父方法的类和公司没有@Transactional注解

谢谢!

【问题讨论】:

  • @mentallurg 谢谢!但这是一个不同的问题,具有不同的特点。这不是重复的问题。

标签: java spring hibernate jpa transactions


【解决方案1】:

您的问题...确保在方法结束时准确刷新数据?不,不是确切方法结束时,而是最新方法结束时。

在事务中,您可以根据需要多次刷新当前状态。刷新意味着您将 JPA 会话与数据库同步。请参阅Hibernate doc 关于此。冲洗并不意味着您的更改是持久的;如果事务稍后回滚,这些更改将自动恢复。 commit 操作执行不同的步骤,其中之一是确保 JPA(例如 Hibernate)会话与 DB 同步,并在需要时调用刷新。如果会话已经同步,则将跳过刷新。

在您所写的 cmets 中,parentMethod 类和方法不是事务性的,method1()method2() 在单独的类中定义。在这种情况下,当调用method1() 时,将启动一个新事务。当这个方法结束时,这个事务将被提交。通过此方法对数据库所做的任何更改都将持久,即无论以后发生什么(例外情况、其他方法中的回滚),这些更改都将保留在数据库中。

可以在here找到与您的案例相关的一些信息,因为以下内容很重要:

  1. 这些方法是否在同一个类中并且
  2. 如果您使用 Spring 自己的 AOP 或 AspectJ。此外,它取决于定义 parentMethod 的类。如果它是事务性的,那么这 2 个调用将在现有事务中运行,并且在第一个被提交后将不会提交。

【讨论】:

  • 谢谢,关于它的两个问题:1)@Transactional(propagation = REQUIRES_NEW) 应该“暂停”父事务直到子事务完成(关于事务性 javadoc),而不是强制提交 2)你理解吗以平等方式提交同花顺?我将更新问题,详细说明您提到的要点
  • 1) 是的,它将暂停外部事务。但是当嵌套的 is 方法完成时,它的事务将在外部事务恢复之前被提交(或在错误的情况下回滚)。 IE。在调用method2() 之前,将提交用于method1() 的事务。 2) 对于commit,我的意思是更改会durable。无论之后发生什么,持久更改都不会恢复。提交不等于刷新。即使不提交事务,您也可以触发刷新。但是commit执行的时候,如果需要也会触发flush。
  • 感谢您的所有回复!你知道@Transactional 方法完成时如何强制刷新吗?
  • 您不需要手动刷新,因为commit 会为您完成。
猜你喜欢
  • 2015-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多