繁体   English   中英

调用entityManager.flush-两次调用,一次调用或根本不调用的效果

[英]Calling entityManager.flush - effects of calling it twice, once or not at all

当方法具有@Transactional批注时,是否必须调用entityManager.flush()或在退出时自动写入数据?

另外,如果我两次调用它,是否总是会出现无交易异常?

    @PersistenceContext(unitName = "CONFIGURATION", type = PersistenceContextType.TRANSACTION)
    private EntityManager entityManager;

@Transactional
    public boolean generate() {
        doStuffToDatabase();
        //entitymanager.flush();
        //entitymanager.flush(); //If I call it twice do I always get a no transaction exception?
    }

当您更改事务内的实体时,实际上并没有更改数据库,而是更改了行的内存模型。 提交事务后,将对内存中模型的更改刷新到数据库,这意味着将执行将数据库状态恢复为模型状态所需的SQL查询。

手动调用entityManager.flush时,您要做的就是在事务完成之前同步这些更改。 这有一些含义:

  • 如果您的事务最终被取消(在调用flush之后发生异常),则Hibernate / JPA将必须执行数据库回滚,这将导致性能损失
  • 如果模型的状态最终违反了数据库中的约束,则手动刷新将在更早的阶段强制执行此错误。 通常,这将在您调用flush而不是事务提交时中断Java的执行。

通常,无需进行手动冲洗。 我唯一能看到的实际收益是我的第二点,如果存在约束违例,必须立即停止执行。 但是在我看来,这是代码的味道,应通过了解您可以做和不能做的更改以及正确的事务设置来轻松避免。

第二次调用flush,并且在这之间没有对模型进行任何更改,将没有任何效果,因为所有更改都已对数据库进行。

@Transactional方法成功完成时,它将提交事务。 在提交事务之前,如果不显式调用它,它将自动在后台调用flush()

如果持久性上下文中有任何挂起的更改,则flush()将立即使JPA发出SQL以插入或更新相关的数据库记录。 第一次刷新后立即再次调用刷新是没有意义的,因为持久性上下文中的所有未决更改已在第一次刷新中更新到数据库。

通常,当我们需要更新大量记录以防止服务器耗尽内存时,通常会手动调用flush() 这个想法是,在对某些记录批次进行更改之后,我们刷新并清除持久性上下文,然后继续处理其他批次。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM