Spring 事务,EntityManager 生命周期

Spring transactions, EntityManager lifecycle

我正在使用 spring 框架开发一个项目。 我有以下架构:所有数据库代码都在 dao classes 中,所有应用程序逻辑都在服务 classes 中,http 请求使用 spring mvc rest 控制器处理。

@Repository
public class UserDao {

    @PersistenceContext
    private EntityManager em;

    public void editUser(User user) {
        ...
    }
}

@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    @Transactional
    public void editUser(User user) {
        ...
    }
}

@RestController
@RequestMapping(value = "/UserCtrl", produces = "application/json;charset=UTF-8")
public class UserCtrl {

    private static final Logger logger = LogManager.getLogger(AppConfig.LOGGER_NAME);

    @Autowired
    private ApplicationContext appContext;

    @RequestMapping(value = "/editUser")
    public ActionResult editUser(@ModelAttribute User user) {
        ActionResult rslt = new ActionResult();

        try {
            UserService userService = appContext.getBean(UserService.class);
            userService.editUser(user);

            rslt.setSuccess(true);
        } catch (Exception ex) {
            logger.error("editUser", ex);
            rslt.setSuccess(false);
        }

        return rslt;
    }
}

这段代码工作正常。 我无法理解的一件事是,当仅在 UserDao class 中注入 EntityManager 时,UserService bean 的 aop 代理如何启动事务。有人可以向我解释一下这是如何工作的以及 spring 框架如何管理 EntityManager 生命周期吗?

感谢任何帮助。

TransactionManager 负责管理事务边界 在 Spring 框架中。 当您使用 @Transactional 注释业务方法时,您正在使用一个方面来检测该方法。 在执行该方法之前,此方面与 TransactionManager 交互,后者决定是否有必要创建新的 Transaction 或使用预先存在的 Transaction。在创建新事务的情况下,从 EntityManagerFactory 创建一个新的实体管理器,并与事务一起关联到当前线程。

EntityManager 负责迭代数据库。当您使用 @PersistenceContext 注入它时,Spring 会向 EntityManager 注入一个代理。 每当在 EntityManager 代理中执行操作时,它都会查找与线程关联的 EntityManager。

根据您提供的代码片段,您正在使用 spring 和一些 JPA 实现,您正在为您的 Web 应用程序使用 J2EE 容器,根据我的猜测,我认为 this 是一篇好文章关于事情是如何运作的。

基本概念:

  1. EntityManager - A class that manages the persistent state(or lifecycle) of an entity.
  2. Persistence Unit - is a named configuration of entity classes.
  3. Persistence Context - is a managed set of entity instances. The entities classes are part of the Persistence Unit configurations.
  4. Managed Entities - an entity instance is managed if it is part of a persistence context and that Entity Manager can act upon it.

基于本文,您通过使用 @PersistenceContext

来使用 Container Managed EntityManager

When a container of the application(be it a Java EE container or any other custom container like Spring) manages the lifecycle of the Entity Manager, the Entity Manager is said to be Container Managed. The most common way of acquiring a Container Managed EntityManager is to use @PersistenceContext annotation on an EntityManager attribute.

注入是这样的:

A Transaction Scoped Entity Manager is returned whenever a reference created by @PersistenceContext is resolved.

Every time an operation is invoked on an Entity Manager, the container proxy(the container creates a proxy around the entity manager while instantiating it ) checks for any existing Persistence Context on the JTA Transaction. If it finds one, the Entity Manager will use this Persistence Context. If it doesnt find one, then it will create a new Persistence Context and associates it with the transaction.

因此实体管理器的生命周期由您的容器管理并且

we work with an instance of EntityManager, the only role of EntityManager is to determine the lifetime of the Persistence Context. It plays no role in dictating how a Persistence Context should behave. To reiterate, Persistence Context is a managed set of Entity instances. Whenever a transaction begins, a Persistence Context instance gets associated with it. And when a Transaction ends(commits for example), the Persistence Context is flushed and get disassociated with the transaction.

简而言之,容器通过您提供的 EntityManagerFactory 实例化您的 EntityManager 并管理它的生命周期,但为您注入 EntityManager 的代理。 TransactionManager 负责创建、提交和……基于您提供的注释的交易,无论何时开始交易,PersistancecContext 与之关联,当交易结束时,它提交 PersistenceContext 的状态。 EntityManager 与 PersistenceContext 一起工作,如果没有提供,EntityManager 会创建一个。只要 EntityManager 没有状态并且状态 (PersistenceContext) 附加到当前事务,它就是线程安全的。

希望对您有所帮助。