我知道em.flush()所做的是清空内部的SQL指令缓存,并立即将其执行到数据库。Correct use of flush() in JPA/Hibernate
但是,当我使用JPA em.flush()将sql导出到数据库时,我发现sql不能立即执行到数据库中。在执行当前操作之前,我无法在数据库中找到数据。
游戏框架中的示例:
em=JPA.em();
Transaction tx=em.getTransaction();
tx.begin();
em.persist(customer);
em.flush();
em.persist(address);
tx.commit();
当我遍历em.flush()时,我在em.flush()行设置了一个断点;
然后,我找不到数据库中的合作伙伴数据。
如果我省略了em.flush();当当前的事务是commited.So时,数据也会进入数据库,那么em.flush()有什么用呢?
发布于 2013-10-12 20:34:15
实体管理器刷新操作将sql发送到数据库,但请记住,当事务正在处理时,通过sql发送到数据库的数据只有在数据库被告知提交时才会持久化。
这是事务期间的一般数据库行为,您可以使用事务设置数据库操作为原子的边界。
即使使用普通jdbc而不是任何orm,您也会看到这种行为,当然,除非为发送的每个sql查询启用了自动提交。在引擎盖下,orm也使用jdbc。因此,对于单个资源事务(例如,单个数据库),通常的成语是首先在jdbc连接上设置autoCommit false,然后通过SQL发送多个插入/更新,然后调用提交连接。如果报告了一些异常,则调用回滚。因此,只有在将提交的最后调用发送到数据库时,数据才会持久化。
更新
您需要理解,没有活动事务的刷新()是行不通的。此外,还有一个叫做FlushMode的东西,它实际上控制着什么时候会发生刷新,您可以看看答案here。理解所有这些的关键是,以insert/updates的形式发送到数据库的数据不会立即使其持久,除非事务已提交,但相同的事务可以访问更改的数据(已更改但未持久化).On数据库端,您可以将其可视化为每个事务的单独区域,其中每个事务可以更改其本身内的数据,但最终进入基础表的数据只有在事务被告知提交后才会这样做。在运行查询之前,提供者还会隐式地调用刷新,查询的结果可能会受到持久上下文状态的影响。例如,如果加载一个实体,然后更改其属性,然后对该实体运行查询,则提供者将看到必须首先将更改发送到其事务处理中的数据库,然后查询该实体,以便加载的属性反映已更改的属性。但是,在事务提交之前,更改后的数据不会持久化到实际的表行。
https://stackoverflow.com/questions/19336760
复制相似问题