2016-12-30 39 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,它不是線程安全的,並且一次只能在一個線程中使用,負責管理實體的狀態。