我知道em.flush()的作用是清空内部SQL指令缓存,并立即将其执行到数据库。 Correct use of flush() in JPA/Hibernate
但是当我使用JPA em.flush()将sql执行到数据库时,我发现sql无法立即执行到数据库。在提交当前的trasaction之前,我无法在数据库中找到数据。
游戏框架中的例子:
em=JPA.em();
Transaction tx=em.getTransaction();
tx.begin();
em.persist(customer);
em.flush();
em.persist(address);
tx.commit();
当我跨过em.flush()时,我在em.flush()行设置断点;
然后,我无法在数据库中找到costomer数据。
如果省略em.flush();当前的trasaction被提交时,数据也会进入数据库。那么,em.flush()的用途是什么?
答案 0 :(得分:0)
实体管理器刷新操作将sql发送到数据库,但请记住,当事务正在进行时,只有在告知数据库提交时,才会通过sql发送到数据库的数据保持不变。
这是事务期间的常规数据库行为,您使用事务将数据库操作的边界设置为原子。
即使使用普通的jdbc而不是任何orm,你也会看到这种行为,除非当然为每个发送的sql查询启用了自动提交。在引擎盖下,orm也使用jdbc。因此,对于单个资源事务(例如,单个数据库),通常的习惯是首先在jdbc连接上设置autoCommit false,然后通过SQL发送多个插入/更新,然后在连接上调用commit。如果报告了一些异常,则调用rollback。因此,只有在最终调用commit时才将数据保存到数据库中。
<强>更新强>
您需要了解没有活动事务的flush()不起作用。还有一个名为FlushMode的东西,它实际上控制着冲洗何时发生 您可以查看答案here。 理解所有这些的关键是以插入/更新的形式发送到数据库的数据不会立即使其持久化,除非事务已提交但相同的事务具有访问权限 更改数据(已更改但尚未保留)。在数据库端,您可以将其视为每个事务的每个事务的单独区域 可以更改自身内部的数据,但最终进入基础表的数据只有在事务被告知提交后才会这样做。同花顺也是 在运行查询之前由提供程序隐式调用,该查询的结果可能受持久上下文状态的影响。例如,如果您加载实体,则更改 它的属性然后运行该实体的查询,然后提供者看到必须首先将更改发送到其事务中的数据库,然后查询实体 以便加载的属性反映更改的属性。但是,在提交事务之前,更改的数据不会持久保存到实际的表行。