【发布时间】:2020-10-12 06:40:54
【问题描述】:
我有一个 Java Spring Boot 应用程序在本地 Oracle 19c 数据库中读取和写入数据。
我有以下CommandLineRunner:
@Override
public void run(String... args) {
final EntityManager em = entityManagerFactory.createEntityManager();
final EntityTransaction transaction = em.getTransaction();
transaction.begin();
em.persist(customer());
//COMMENT1 em.flush();
/*COMMENT2
Query q = em.createQuery("from " + Customer.class.getName() + " c");
@SuppressWarnings("unchecked")
final Iterator<Object> iterator = (Iterator<Object>) q.getResultList().iterator();
while (iterator.hasNext()) {
Object o = iterator.next();
final Customer c = (Customer) o;
log.info(c.getName());
}
*/
transaction.rollback();
}
当我运行此代码时,使用数据包嗅探器监控应用程序和数据库之间的 TCP 流量,我看到了我的预期:对话中没有什么特别有趣的,因为 em.persist(customer()) 不会被刷新。
当我将代码包含在 COMMENT1 中时,我惊讶地发现对话看起来一样 - 连接握手后没有什么有趣的东西。
但是,当我将代码包含在 COMMENT2 中时,我会得到一个更完整的 TCP 对话。现在,捕获的数据包显示写入操作确实已刷新到数据库,并且我还可以看到读取操作的证据以列出其后的所有实体。
为什么只删除 COMMENT1 时,TCP 会话没有反映显式的flush()?为什么我需要包含 COMMENT2 才能看到在 TCP 连接中捕获的 insert into customer... 语句?
【问题讨论】:
-
我想这可以回答你的问题:stackoverflow.com/questions/11048177/…
-
@JanosVinceller 它没有。我的问题是“为什么刷新实际上不刷新到数据库” - 在另一个问题中没有回答。
-
flush 方法的 javadoc 说它 - 将持久性上下文同步到底层数据库。 docs.oracle.com/javaee/7/api/javax/persistence/… 实际行为可能取决于实现。但是根据 API,您看到的内容还可以。此外,一旦你有了一个 EM,你应该通过 EM(仅)执行所有的数据库操作,这样你就有了最新的状态。 EM.flush() 根本不需要立即将更改推送到数据库以显示该状态,对吧?
标签: java database oracle jpa tcp