【发布时间】:2011-08-26 12:59:11
【问题描述】:
就目前而言,我正在使用 JSF 请求范围的 bean 来执行我的所有 CRUD 操作。我敢肯定你很可能知道 Tomcat 不提供容器管理的持久性,所以在我的 CRUD 请求 bean 中,我使用 EnityManagerFactory 来获取实体管理器的折叠。现在关于我选择使用请求范围 bean 来完成此任务的有效性,它可能(再次)可以讨论,但我一直试图将它放在我在你给我链接的文章中读到的内容中到,特别是第一个和第二个。从我收集的信息来看,EclipseLink 默认使用二级缓存来存储缓存的实体。在 ExlipseLink 示例 - JPA 缓存网站上它说:
共享缓存在持久化单元(EntityManagerFactory,或服务器)的持续时间内存在
现在,在对 CRUD 请求 bean 进行调用期间,这不会使我的缓存实体存活一小部分时间,因为 bean 被销毁的那一刻,以及 EntityManagerFactory 缓存也是如此。上面句子“EntityManagerFactory,或服务器”的最后一部分也让我感到困惑.. 或服务器在这种情况下的确切含义以及如何控制它。如果我使用@Cache 注释并设置适当数量的 expire 属性,那么无论我的 EntityManagerFactory 是否已被破坏,这是否会完成这项工作并将实体存储在服务器 L2 缓存中?
我知道有很多考虑要做,每个应用程序都有特定的要求。从我的角度来看,配置 L2 缓存可能是最理想的(如果不仅是在 Tomcat 上)优化事情的选项。引用您的第一个链接:
L2 缓存的优点是:
- 避免对已加载实体的数据库访问
- 读取频繁访问的未修改实体更快
L2缓存的缺点是:
- 大量对象的内存消耗
- 更新对象的过时数据
- 并发写入(乐观锁异常,或悲观锁)
- 频繁或同时更新的实体的可扩展性差
您应该为以下实体配置 L2 缓存:
- 经常阅读
- 不经常修改
- 如果陈旧则不重要
以上几点几乎都适用于我的应用。除其他外,它的核心是持续不断地阅读实体并将其显示在网站上(该应用程序将用作列出属性的门户)。应用程序中还构建了一个小型购物车,但出售的产品不是以库存形式出现的有形物品,而是服务。在这种情况下,陈旧的实体没有问题,而且我认为这不是并发性的,因为产品(这里是服务)永远不会被写入。所以实体会经常被读取,它们会被不频繁地修改(并且那些被修改的东西无论如何都不是购物车的一部分,即使是那些也很少被修改),因此如果过时并不重要。最后,前两点似乎正是我所需要的,即避免对已加载实体的数据库访问和快速读取经常访问的未修改实体。但是有一点仍然让我有点担心:大量对象的内存消耗。是不是和我原来的问题很像?
我目前的理解是有两种选择,只有一种适用于我的情况:
-
为了能够将长期缓存的工作委托给持久层,而不是我需要访问 PersistenceContext 并创建会话范围的 bean 并设置 PersistenceContextType.EXTENDED。 (此选项不适用于我,无法访问 PersistenceContext)。
-
在实体上配置 L2 @Cache 注释,或者像上面的选项 1 一样创建一个会话范围的 bean,它将处理长期缓存。但是这些不就是回到我原来的问题吗?
我真的很想听听您的意见,看看您认为解决这个问题的合理方法是什么,或者您在以前的项目中是如何解决这个问题的。哦,还有一件事,只是为了确认.. 使用 @Cache 注释实体时,所有链接的实体都将被缓存,所以我不必对所有实体进行注释?
再次感谢所有 cmets 和指针。
谢谢你的回答..当你说
“在 Tomcat 中,最好有一些静态管理器在服务器运行期间保持 EntityManagerFactory。”
这是否意味着我可以在应用程序中声明和初始化静态 EntityManagerFactory 字段,以便以后在应用程序的整个生命周期中由所有 bean 使用?
【问题讨论】:
标签: caching jakarta-ee jpa jpa-2.0 entities