ChatGPT解决这个技术问题 Extra ChatGPT

Spring数据jpa中save和saveAndFlush的区别

我正在尝试通过 JpaRepository 测试一些 CRUD 操作来学习 Spring Data JPA。

我遇到了两种方法 savesaveAndFlush。我不明白这两者之间的区别。在调用 save 时,我的更改也被保存到数据库中,那么 saveAndFlush 有什么用。


H
Hearen

saveAndFlush 上,更改将立即在此命令中刷新到 DB。对于 save,这不一定正确,并且可能只保留在内存中,直到发出 flushcommit 命令。

但请注意,即使您刷新事务中的更改并且不提交它们,在此事务中提交之前,外部事务仍然看不到这些更改。

在您的情况下,您可能使用某种事务机制,如果一切正常,它会为您发出 commit 命令。


“在此事务中提交之前,外部事务将不可见”这取决于其他事务的隔离级别。如果一个事务的隔离级别是READ_UNCOMMITTED,那么它会看到其他事务已经刷新但尚未提交的内容。
但是,在我的项目中,我使用了 save()、saveAll() 并且它在 DB 中持续存在而无需显式提交或刷新调用。那我为什么更喜欢 saveAndFlush 呢?刷新模式所有这些都处于默认模式
Satish Patro,saveAndFlush() 用于立即刷新。如果您使用 save(),则刷新操作将由 JPA 稍后处理。
H
Hearen

根据您使用的休眠刷新模式(AUTO 是默认值)save 可能会也可能不会立即将您的更改写入数据库。当您调用 saveAndFlush 时,您将强制执行模型状态与数据库的同步。

如果您使用刷新模式 AUTO 并且您正在使用您的应用程序先保存然后再次选择数据,您将不会看到 save()saveAndFlush() 之间的 bahvior 差异,因为选择首先触发了刷新。请参阅 documention


抱歉,但如果我 save 一个实体又是同一个实体,您的意思是 save 第二个命令不会引发重复异常,例如?
@Bludream 是的,据我了解,对 save 的调用是幂等的。有关详细信息,请参阅此 thread
D
Dinushika Rathnayake

这两种方法都用于将实体保存到数据库中。刷新是将持久化上下文的状态与底层数据库同步的过程。

使用 saveAndFlush 方法时,数据会立即刷新到数据库,要使用 save 方法,我们需要显式调用 flush() 方法。使用刷新可以在同一事务期间但在提交之前的稍后步骤中读取已保存的更改。所以如果不需要提交,仍然可以回滚。


G
Geeth

在 Spring Data Jpa save() 方法中,我们可以将实体保存到数据库中。它属于Spring Data定义的CrudRepository接口。

当我们使用 save() 方法时,与保存操作相关的数据不会被刷新到数据库,除非并且直到显式调用 flush() 或 commit() 方法。

例如,让我们创建一个实体和 JPA 存储库。

@Data
@Entity
public class User{

    @Id
    private Long id;
    private String name;
}


public interface UserRepository extends JpaRepository<User, Long> {
}

然后可以像这样使用save()方法,

userRepository.save(new User(1L, "Geeth"));

saveAndFlush() 方法不同于 save()saveAndFlush() 方法在执行期间立即刷新数据。该方法属于 Spring Data JPA 的 JpaRepository 接口。您可以按如下方式使用它。

userRepository.saveAndFlush(new User(2L, "Sam"));

通常,当我们的业务逻辑需要稍后在同一事务期间但在提交之前读取保存的更改时,我们会使用此方法。

例如,想象一个场景,我们必须执行一个存储过程,该过程需要我们将要保存的实体属性。在这种情况下,save() 方法将不起作用,因为更改与数据库不同步,并且存储过程不知道更改。 saveAndFlush() 方法非常适合这种情况。