【问题标题】:How Spring+JPA integration actually worksSpring+JPA 集成的实际工作原理
【发布时间】:2014-06-23 08:20:00
【问题描述】:

一个简单的银行应用程序:

注意事项:

  • 使用 Spring+JPA 和 EclipseLink 作为 JPA 提供程序实现
  • EntityManager 使用 @PersistenceContext 注入 BaseDaoImpl
  • DAO 自动装配到服务 bean 中
  • @Transactional 注解用于服务方法

问题:

  1. 是每个 DAO 都有自己的 EntityManager 实例还是共享实例?
  2. 如果它们是单独的实例,事务如何工作?
  3. 如果是共享实例,连接何时关闭?在应用程序关闭时?这是否意味着整个应用程序只有一个连接,无论 DAO/实体的数量如何,并且在应用程序生命周期内保持打开状态?

【问题讨论】:

    标签: java spring jpa


    【解决方案1】:

    使用@PersistenceContext 注入的EntityManager 实例是一个代理,它将实际工作委托给与当前事务关联的EntityManager

    换句话说,它的工作原理如下:

    • 当您进入@Transactional 范围时,会创建新事务并与当前线程关联
    • 当您在 DAO 中调用 EntityManager 的方法时,调用将委托给与当前事务关联的 EntityManager(如果不存在,将创建新的 EntityManager
    • 当您离开 @Transactional 范围时,事务被提交,与之关联的 EntityManager 被关闭

    【讨论】:

      【解决方案2】:

      使用@PersistenceContext 注入 DAO 的实际上不是底层 ORM 的实体管理器实现,而是 Spring 代理,它将调用委托给 实际的基础实体经理。代理的具体类通常是SharedEntityManagerInvocationHandler

      底层实体管理器的范围通常是 Spring 托管事务的范围(另一个是扩展范围,这里没有问题) Spring 事务管理器(当 JPA 用作数据访问时通常为 JpaTransactionManager)将 EntityManager 绑定到当前线程,随后从这里检索实体管理器,直到事务提交。对于新的交易,同样的事情再次发生。 你可以看看JpaTransactionManagerdoBegin方法的源代码,这一切都发生了。

      【讨论】:

        猜你喜欢
        • 2011-11-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-16
        • 1970-01-01
        • 2012-06-28
        • 1970-01-01
        相关资源
        最近更新 更多