2011-08-26 86 views
1

目前的情况是我使用的是JSF请求范围豆做我的CRUD操作。正如我相信你最有可能知道Tomcat没有提供容器管理的持久性,所以在我的CRUD请求bean中,我使用EnityManagerFactory来获得Enity manager的折叠。现在,我的选择使用请求的有效性范围的bean完成这个任务,它可能是开放的讨论(再次),但我一直在试图把它放在我的文章已经阅读上下文,你给我链接特别是第一个和第二个。从我收集的内容中,EclipseLink默认使用存储缓存实体的二级缓存。在ExlipseLink例子 - JPA缓存网站上面说:JPA2实体缓存

持久化单元(EntityManagerFactory的,或服务器)

的时间共享缓存中现在并不使我的缓存的实体住了在正在对CRUD请求bean进行调用期间的一小部分时间,因为bean被销毁的时刻以及EntityManagerFactory所以是缓存。此外,上面一句的最后一部分“的EntityManagerFactory,或服务器”让我困惑..什么正是由或服务器在这方面的意思,一个人如何控制它。如果我使用@Cache注释和到期属性的设置适当的量,将是做的工作,保持存储在服务器的二级缓存比实体,不管我的EntityManagerFactory是否已被破坏?

我知道有很多的考虑要做,每个应用程序都有具体的要求。从我的角度来看,配置L2缓存可能是最好的选择(如果不仅仅是Tomcat),可以优化事情。从你的第一个链接引用:

L2高速缓存的优点是:

  • 避免数据库访问的已加载实体
  • 更快的读取频繁访问未修改实体

缺点L2高速缓存的有:

  • 内存消耗大量的对象
  • 陈旧的数据更新的对象
  • 并发写入(乐观锁定异常,或悲观锁)
  • 糟糕的可伸缩性频繁或同时更新实体

你应该配置L2缓存是实体:读

  • 经常
  • MODI如果陈旧

田间很少

  • 并不重要,几乎所有上述各点适用于我的应用程序。除此之外,它的核心是持续不断地阅读实体并将其展示在网站上(该应用将作为列表属性的入口)。在应用程序中还有一个小型购物车,但销售的产品不是以库存而是以服务形式出现的有形物品。在这种情况下,陈旧的实体是没有问题的,所以我认为,并不是因为产品(这里的服务)永远不会写入并发。所以这些实体会经常被读取,而且它们很少会被修改(而且那些修改不会成为购物车的一部分,甚至那些修改也很少),因此如果失效的话不是关键。最后,前两点似乎正是我所需要的,即避免数据库访问已经加载的实体并快速读取经常访问的未修改的入口。但是,有一点仍然关系到我的缺点:大量对象的内存消耗。这与我原来的问题不一样吗?

    我现在的理解是,有两个选项,其中只有一个适用于我的情况:

    1. 为了能够更长期缓存的工作委托给持久层比我更需要有访问PersistenceContext并创建会话作用域bean并设置PersistenceContextType.EXTENDED。 (这个选项不适用于我,不能访问PersistenceContext)。

    2. 在实体上配置L2 @Cache注释,或者像上面的选项1一样,创建一个会处理长期缓存的会话作用域bean。但是,这些不是回到我原来的问题吗?

    我很想听听你的意见,看看你认为可能是解决这个合理的方式,或者是你如何已在以前的项目接近它。哦,还有一件事,只是为了确认..当使用@Cache注释一个实体时,所有链接的实体都将被缓存,所以我不必对它们进行注释?

    再次所有的评论和指针非常赞赏。


    感谢您的阅读答题..当你说

    “在Tomcat中,你将是最好有保存到EntityManagerFactory的服务器期间一些静态的经理。”

    这是否意味着我可以例如声明和初始化应用程序范围内的静态EntityManagerFactory字段以供所有的bean随后在整个应用程序的整个生命周期中使用?

  • 回答

    0

    EclipseLink默认使用共享缓存。这是从EntityManagerFactory访问的所有EntityManagers共享的。您无需执行任何操作即可启用缓存。

    通常,您不希望为每个请求创建新的EntityManagerFactory,只需要新建一个EntityManager。创建一个新的EntityManagerFactory非常昂贵,所以不是一个好主意,即使忽略缓存(它有自己的连接池,必须初始化元数据等)。

    在Tomcat中,您最好拥有一些静态管理器,该静态管理器在服务器期间保存到EntityManagerFactory中。请不要关闭它,或者在Servlet被销毁时关闭它。