我正在收集有关flush()方法的信息,但我不太清楚何时使用它以及如何正确使用它。据我所知,我的理解是持久化上下文的内容将与数据库同步,即发出未完成的语句或刷新实体数据。
现在我得到了两个实体A
和B
的场景(在一对一关系中,但不是由JPA强制执行或建模的)。A
有一个手动设置的复合PK,也有一个自动生成的身份字段recordId
。此recordId
应作为A
的外键写入实体B
。我在单个事务中保存A
和B
。问题是自动生成的值A.recordId
在事务中不可用,除非我在A
上调用em.persist()
之后显式调用em.flush()
。(如果我有一个自动生成的身份PK,那么实体中的值将直接更新,但这里不是这种情况。)
在事务中使用em.flush()
时,是否会造成任何危害?
发布于 2010-11-25 18:22:33
可能em.flush()
的确切细节依赖于实现。总之,像Hibernate这样的JPA提供者可以缓存它们应该发送到数据库的SQL指令,通常直到您实际提交事务为止。例如,您调用em.persist()
,Hibernate记得它必须进行数据库插入,但直到您提交事务时才实际执行指令。Afaik,这主要是出于性能原因。
在某些情况下,无论如何您都希望立即执行SQL指令;通常在需要某些副作用的结果时,比如自动生成的键或数据库触发器。
em.flush()
所做的是清空内部SQL指令缓存,并将其立即执行到数据库中。
归根结底:没有什么坏处,只会对性能造成(轻微)影响,因为您正在覆盖JPA提供者关于向数据库发送SQL指令的最佳时机的决定。
发布于 2018-01-09 03:25:16
实际上,em.flush()
不仅仅发送缓存的SQL命令。它尝试将持久化上下文同步到底层数据库。如果您的缓存包含要同步的集合,则可能会在您的进程上造成大量时间消耗。
请注意使用它。
发布于 2019-06-12 17:14:11
当在事务中使用em.flush()时,它会造成任何危害吗?
是的,它可能会在数据库中持有锁的持续时间超过必要的时间。
通常,当使用JPA时,您将事务管理委托给容器(也称为CMT -在业务方法上使用@ transaction注解),这意味着事务在进入方法时自动启动,并在结束时提交/回滚。如果让EntityManager处理数据库同步,sql语句的执行将仅在提交之前触发,从而导致数据库中的锁很短。否则,手动刷新的写操作可能会在手动刷新和自动提交之间保留锁,根据剩余的方法执行时间,锁可能会很长。
请注意,某些操作会自动触发刷新:对同一会话执行本机查询(EM状态必须刷新才能被SQL查询访问),使用本机生成的id插入实体(由数据库生成,因此必须触发insert语句,以便EM能够检索生成的id并正确管理关系)
https://stackoverflow.com/questions/4275111
复制相似问题