【问题标题】:JPA use in about save(flush) in play framework 1.xJPA 在 play framework 1.x 中关于 save(flush) 的使用
【发布时间】:2013-10-12 16:53:52
【问题描述】:

我知道 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();提交当前事务时,数据也会进入数据库。那么,em.flush() 有什么用?

【问题讨论】:

    标签: hibernate jpa


    【解决方案1】:

    实体管理器刷新操作将 sql 发送到数据库,但请记住,当事务正在进行时,只有当数据库被告知提交时,通过 sql 发送到数据库的数据才会被持久化。

    这是事务期间的一般数据库行为,您可以使用事务来为数据库操作设置原子边界。

    即使使用纯 jdbc 而不是任何 orm,您也会看到这种行为,除非为每个发送的 sql 查询启用自动提交。在底层,orm 也使用 jdbc。所以对于单个资源事务(例如单个数据库),通常的习惯用法是先在jdbc连接上设置autoCommit为false,然后通过SQL发送多个insert/updates,然后在连接上调用commit。如果报告了一些异常,则调用回滚。所以数据只有在最终的 commit 调用发送到数据库时才会持久化。

    更新

    您需要了解,没有活动事务的 flush() 是行不通的。还有一个叫做 FlushMode 的东西,它实际上控制刷新何时发生 你可以看看答案here。 理解这一切的关键是,以插入/更新形式发送到数据库的数据不会立即使其持久化,除非事务已提交但同一个事务具有访问权限 到已更改的数据(已更改但尚未持久化)。在数据库端,您可以将其可视化为每个事务的单独区域,其中每个事务 可以更改自身内部的数据,但最终进入基础表的数据只有在事务被告知提交后才会这样做。冲洗也是 在运行其结果可能受持久上下文状态影响的查询之前由提供者隐式调用。例如,如果你加载一个实体,然后改变 它的属性,然后对该实体运行查询,然后提供者看到必须首先在其事务中将更改发送到数据库,然后查询该实体 以便加载的属性反映更改的属性。但是,在提交事务之前,更改的数据不会持久化到实际的表行。

    【讨论】:

    • 谢谢,我明白了。但是如果我省略了 em.flush();提交当前事务时,数据也会进入数据库。所以,如何为我使用 em.flush()。
    • 您好,请给我一些建议,我想我了解如何使用flush()。persist()意味着数据由JPA保存,而数据在flush()之前不会进入数据库执行。所以我有一个测试,System.out.println("Customercount :"+Customer.count());//0 manager.persist(custemer); System.out.println("Customer count :"+Customer.count());//1 所以我认为控制台结果应该是 0,0 ,而不是 0,1
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-08
    相关资源
    最近更新 更多