Mic*_*Sim 107 java persistence hibernate jpa transactions
我正在收集有关flush()方法的信息,但我不清楚何时使用它以及如何正确使用它.根据我的阅读,我的理解是持久化上下文的内容将与数据库同步,即发出未完成的语句或刷新实体数据.
现在,我得到下列设想两个实体A和B(在一比一的关系,而不是由JPA执行或模拟).A有一个复合PK,它是手动设置的,还有一个自动生成的IDENTITY字段recordId.这recordId应该B作为外键写入实体A.我正在保存A并B进行单笔交易.问题是自动生成的价值A.recordId是不可用的事务中,除非我做的一个显式调用em.flush()打完电话后em.persist()上A.(如果我有一个自动生成的IDENTITY PK,那么该值将在实体中直接更新,但这不是这里的情况.)
可以em.flush()在一个事务中使用时造成什么伤害?
Fla*_*vio 141
可能确切的细节em.flush()依赖于实现.总的来说,像Hibernate这样的JPA提供程序可以缓存它们应该发送到数据库的SQL指令,通常直到你实际提交事务为止.例如,你调用em.persist(),Hibernate记得它必须创建一个数据库INSERT,但在提交事务之前实际上并不执行该指令.Afaik,这主要是出于性能原因.
无论如何,在某些情况下,您希望立即执行SQL指令; 通常当您需要某些副作用的结果时,例如自动生成的密钥或数据库触发器.
什么em.flush()是清空内部SQL指令缓存,并立即执行它到数据库.
底线:没有造成任何伤害,只有你可以有一个(次要)性能命中,因为你重写了JPA提供者关于将SQL指令发送到数据库的最佳时机的决定.
在事务中使用 em.flush() 会造成任何伤害吗?
是的,它可能会在数据库中持有锁的时间超过必要的时间。
一般来说,使用 JPA 时,您将事务管理委托给容器(又名 CMT - 在业务方法上使用 @Transactional 注释),这意味着进入方法时会自动启动事务,并在最后提交/回滚。如果让 EntityManager 处理数据库同步,则 sql 语句的执行将仅在提交之前触发,从而导致数据库中出现短暂的锁。否则,您的手动刷新写入操作可能会在手动刷新和自动提交之间保留锁定,根据剩余方法执行时间,该锁定可能会很长。
请注意,某些操作会自动触发刷新:对同一会话执行本机查询(必须刷新 EM 状态才能通过 SQL 查询访问),使用本机生成的 id 插入实体(由数据库生成,因此插入语句必须是因此 EM 能够检索生成的 id 并正确管理关系)