2016-12-30 35 views
2

的Java Web
Spring MVC框架通过多线程(多请求)被称为春@Transactional方法

在我的服务水平,我写了一个@Transactional方法。在那种方法中,我更新数据库中的一些数据,然后再从数据库中读取数据。 我感到惊讶的是,当几个请求在同一个线程中出现时,数据更改是可见的(应该是这样),但数据更改在其他线程中不可见。
构建一个事务的方法不是不同的线程?
如果我仍然想使用事务,并且我希望在不同线程中调用的方法在一个事务中(数据的更改可以互相看到),我应该怎么做?

回答

4

我从书上Professional Java for Web Applications by Nicholas S. Williams

使用线程的事务和实体管理器

交易范围仅限于交易中开始线程复制本。该 事务管理器,然后链接在交易的生命周期中在同一线程 中使用的管理资源的交易。使用Java Persistence API时,与 一起使用的资源是EntityManager。它是Hibernate ORM的Session和JDBC的 Connection的功能等同物。通常,在开始事务并执行JPA操作之前,您将从EntityManagerFactory 获得EntityManager。但是,这并不适用于代表您管理事务的Spring Framework模型。 此问题的解决方案是org.springframework.orm.jpa.support.SharedEntityManagerBean。当您在Spring Framework中配置JPA时,它将创建代理EntityManager接口的 a SharedEntityManagerBean。然后,该代理将 注入到JPA存储库中。当EntityManager方法在此代理实例调用时, 下发生的背景:

➤➤如果当前线程已经拥有了一个真正的EntityManager有活动的事务,它 代表调用上EntityManager方法。

➤➤否则,Spring框架获得来自 EntityManagerFactoryEntityManager,启动一个事务,并结合两到当前线程。然后 委托对该方法的调用EntityManager。 当交易被提交或回滚时,Spring将该交易和该线程绑定,然后关闭EntityManager。未来@Transactional 对同一线程(即使在同一请求中)的操作再次启动该过程,从工厂获取 新的EntityManager并开始新的事务。这样,没有两个线程同时使用EntityManager,并且给定线程在任何给定时间只有一个事务和一个活动的 EntityManager

(我转述这一点上篇)

我认为它的自我解释,并回答你的问题。但我想补充一点,如果你不使用Spring MVC,那么你将在Hibernate中使用SessionFactory获得会话。休眠Session代表从开始到结束的事务生活。根据您的应用程序架构如何,可能不到一秒或几分钟;在Web应用程序中,它可以是请求中的多个事务中的一个,持续整个请求的事务或跨多个请求的事务中的一个。 A Session,它不是线程安全的,并且一次只能在一个线程中使用,负责管理实体的状态。