【问题标题】:Can reference to javax.persistence.EntityManager be cached?可以缓存对 javax.persistence.EntityManager 的引用吗?
【发布时间】:2010-09-03 14:30:22
【问题描述】:

我们能否缓存对 EntityManager 的引用。

至于我们的要求,我们没有将 EntityManger 注入到其他 EJB 中,而是有一个实用程序类,它将返回对 entitymanager 的引用。 问题是每次我们需要获取参考时,我们都在进行 JNDI 查找。

为了避免 JNDI 查找,我们希望在 hashmap 等中缓存对实体管理器的引用。

它似乎有效,但我有几个疑问: 1.如果我们缓存entityManager,那么只要引用处于活动状态,它就会保持连接吗? 2. 交易管理会有变化吗?

提前谢谢你。

【问题讨论】:

  • 我不会对此表示赞赏。 EM 不应该像那样被缓存。这些 JNDI 查找真的是瓶颈吗?

标签: java hibernate jpa ejb-3.0


【解决方案1】:

EntityManagers 不是线程安全的,因此您至少需要将它们缓存在线程本地或通过线程标识符或其他东西在映射中。

问题 1)这是特定于您的底层提供商的,但在大多数情况下,是的,打开 EntityManager 意味着您正在保持数据库连接。

问题 2) 可能,但您没有说明您当前使用什么策略进行事务管理。

另一个大问题是,如果您根据规范正确使用 EM,则需要在出现异常时处理它并获取一个新的。这意味着您需要正确管理该缓存,只要它可能出现异常。

听起来您可能正在尝试将 JPA 用作 JDBC 包装器。为每个单独的 SQL 语句获取一个新的 EM,然后将其处理掉。您还没有提供有关系统架构的任何信息,也许像 Open EntityManager in View 模式这样的中间立场可以在不尝试发明新轮子的情况下缓解您的问题?

【讨论】:

    【解决方案2】:

    至于我们的要求,我们没有将 EntityManger 注入到其他 EJB 中,而是有一个实用程序类,它将返回对 entitymanager 的引用。

    可能有很好的理由,但究竟是什么限制,你为什么不能使用注入?无论如何,查找是否被确定为问题?你量过什么吗?与总处理时间相比,查找代表多少时间?是不是可以忽略不计?

    为了避免 JNDI 查找,我们希望在 hashmap 等中缓存对实体管理器的引用...

    说实话,您在这里提问这一事实强烈暗示您不应该这样做。事务管理呢?异常处理怎么样(你应该在异常后丢弃 EM)?内存管理呢?

    如果我们缓存 entityManager,那么只要引用处于活动状态,它就会保持连接吗?

    资源(只要已经获得)不会被释放,所以是的。来自 Hibernate EM 文档:

    5.1. Entity manager and transaction scopes

    EntityManagerFactory 是一个 创建昂贵的线程安全对象 旨在由所有人共享 应用程序线程。它被创建 一次,通常在应用程序启动时。

    EntityManager 很便宜, 应该是非线程安全的对象 使用一次,用于单一业务 过程,单个工作单元,以及 然后丢弃。 一个EntityManager 不会获得 JDBC 连接(或 数据源),除非需要, 这样您就可以安全地打开和关闭 EntityManager 即使你不是 确保需要访问数据 为特定请求提供服务*。 (这个 一旦你变得重要 实施以下一些 使用请求拦截的模式。)

    ...

    后来:

    5.2.1. Non-managed environment

    ...

    close() 的调用标志着EntityManager 的结束。 close() 的主要含义是释放资源 - 确保您始终关闭并且永远不会超出保证的 finally 块

    没有魔法。如果 EM 需要与数据库交互,它将获取一个连接。如果您不close EntityManager,则不会释放此连接。如果需要,请查看底层 Hibernate Session 的源代码。

    交易管理会有变化吗?

    好吧,您没有说明您当前正在使用什么(容器管理的实体管理器?应用程序管理的实体管理器?),并且您没有解释事务是如何管理的(JTA 实体管理器?资源-本地实体经理?)。无论如何,答案是……可能。

    也许您应该解释一下当前的工作方式(在开始缓存实体管理器之前)。

    而且我会亲自衡量事情,我不相信有问题。除非你证明有问题,否则你试图做的事情是不值得的。

    【讨论】:

    • 谢谢帕斯卡。我们正在使用 CMP 我正在使用 jboss,我看到了 DataSource 连接池 MBean。即使在获得实体管理器后,连接池计数(可用连接显示 20 - 这是实际可用的计数),这意味着 EM 没有保持连接。我们需要使用单独的实体管理器,因为与 db 的连接是在运行时识别的。我在 ibm.com 上读到,查找需要时间。我从这个ibm.com/developerworks/java/library/j-ejb0924.html 得到了一个想法,并试图微调我的应用程序。谢谢你:)
    • @Vineyard EM 中的连接是延迟加载的。但是一旦获得,直到你关闭它才会被释放(检查代码,没有魔法)。而且您不应该根据您在 2002 年一篇关于 EJB 2.x 的尘土飞扬的文章中阅读的内容做出选择。正如我所说,衡量事物。但如果你坚持,祝你好运:)
    猜你喜欢
    • 2013-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-13
    • 1970-01-01
    • 2012-11-02
    • 1970-01-01
    相关资源
    最近更新 更多