繁体   English   中英

JPA和一级缓存,重点是什么?

[英]JPA and first level cache, whats the point?

EntityManager为检索到的对象维护第一级缓存,但是如果您想拥有线程安全应用程序,则需要为每个事务创建和关闭entityManager。

那么,如果为每个事务创建和关闭这些实体,那么第1级缓存的重点是什么? 或者,如果您在单线程中工作,则entityManager缓存是否可用?

重点是让应用程序像您期望的那样工作,并且这不会像地狱一样慢。 我们来举个例子:

Order order = em.find(Order.class, 3L);
Customer customer = em.find(Customer.class, 5L);
for (Order o : customer.getOrders()) { // line A
    if (o.getId().longValue == 3L) {
        o.setComment("hello"); // line B
        o.setModifier("John"); 
    }
}

System.out.println(order.getComment)); // line C

for (Order o : customer.getOrders()) { // line D
    System.out.println(o.getComment()); // line E
}

在A行,JPA执行SQL查询以加载客户的所有订单。

在C行,您希望打印什么? null"hello" 您希望打印“hello”,因为您在B行修改的顺序与第一行中加载的顺序相同。 如果没有第一级缓存,这是不可能的。

在D行,您不希望从数据库再次加载订单,因为它们已经在A行加载。如果没有第一级缓存,这是不可能的。

在E行,您希望再次为订单3打印“hello”。如果没有第一级缓存,这是不可能的。

在B行,您不希望执行更新查询,因为可能会对同一实体进行许多后续修改(如下一行)。 因此,您希望在事务结束时尽可能晚地将这些修改写入数据库。 如果没有第一级缓存,这是不可能的。

第一级缓存用于其他目的。 它基本上是JPA放置从数据库检索的实体的上下文。

性能

因此,要开始说明显而易见的事情,它可以避免在事务处理过程中检索记录时必须检索记录,并在提高性能时使用某种形式的缓存。 另外,考虑延迟加载。 如何在没有缓存的情况下实现它来记录已经延迟加载的实体?

循环关系

这种缓存目的对于实施适当的ORM框架至关重要。 在面向对象的语言中,对象图通常具有循环关系。 例如,具有Employee对象和Employee对象的Department属于Department。

没有上下文(也称为工作单元 ),很难跟踪您已经拥有ORMed的记录,并且最终会创建新对象,在这种情况下,您甚至可能最终陷入无限循环。

跟踪变化:提交和回滚

此外,此上下文会跟踪您对对象所做的更改,以便在事务结束时稍后可以保留或回滚它们。 如果没有这样的缓存,您将被迫在发生更改时立即将更改刷新到数据库,然后您无法回滚,也无法优化将它们刷新到商店的最佳时刻。

对象身份

对象标识在ORM框架中也至关重要。 也就是说,如果您检索员工ID 123,那么如果您在某个时候需要该员工,则应始终获取相同的对象,而不是包含相同数据的新Object。

这种类型的缓存不是由多个线程共享的,如果是这样的话,你会牺牲性能并强迫每个人付出代价,即使他们可以使用单线程解决方案。 除了你最终会得到一个更复杂的解决方案,就像用火箭筒杀死苍蝇一样。

这就是为什么如果您需要的是共享缓存,那么您实际上需要一个二级缓存,并且还有实现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM