日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring @Transactional实际如何工作?

發布時間:2023/12/3 javascript 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring @Transactional实际如何工作? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在本文中,我們將深入探討Spring事務管理。 我們將討論@Transactional在@Transactional如何真正工作。 其他即將發布的帖子將包括:

  • 如何使用傳播和隔離等功能
  • 主要陷阱是什么以及如何避免它們

JPA和事務管理

重要的是要注意,JPA本身不提供任何類型的聲明式事務管理。 在依賴項注入容器之外使用JPA時,開發人員需要以編程方式處理事務:

UserTransaction utx = entityManager.getTransaction(); try { utx.begin(); businessLogic();utx.commit(); } catch(Exception ex) { utx.rollback(); throw ex; }

這種管理事務的方式使代碼中的事務范圍非常清楚,但是有一些缺點:

  • 它是重復性的并且容易出錯
  • 任何錯誤都會產生很大的影響
  • 錯誤很難調試和重現
  • 這降低了代碼庫的可讀性
  • 如果此方法調用另一個事務方法怎么辦?

使用Spring @Transactional

使用Spring @Transactional ,上述代碼簡化為:

@Transactionalpublic void businessLogic() {... use entity manager inside a transaction ...}

這更加方便和易讀,是當前在Spring中推薦的處理事務的推薦方法。

通過使用@Transactional ,可以自動處理許多重要方面,例如事務傳播。 在這種情況下,如果businessLogic()調用了另一個事務方法,則該方法可以選擇加入正在進行的事務。

潛在的不利之處在于,這種強大的機制隱藏了幕后發生的事情,從而在無法正常工作時很難進行調試。

@Transactional的關鍵點之一是要考慮兩個單獨的概念,每個概念都有自己的范圍和生命周期:

  • 持久性環境
  • 數據庫事務

事務注釋本身定義了單個數據庫事務的范圍。 數據庫事務在持久性上下文的范圍內發生。

持久性上下文在JPA中是EntityManager ,使用Hibernate Session在內部實現(當使用Hibernate作為持久性提供程序時)。

持久性上下文只是一個同步器對象,該對象跟蹤一組有限的Java對象的狀態,并確保最終將這些對象上的更改持久化回到數據庫中。

這與數據庫事務的概念非常不同。 一個實體管理器可用于多個數據庫事務 ,而實際上經常是這樣。

EntityManager何時跨多個數據庫事務?

最常見的情況是,當應用程序使用“打開視圖中的會話”模式來處理延遲的初始化異常時,請參見上一篇博客文章,以了解其優缺點 。

在這種情況下,在視圖層中運行的查詢與用于業務邏輯的查詢不在單獨的數據庫事務中,但是它們是通過同一實體管理器進行的。

另一種情況是,開發人員將持久性上下文標記為PersistenceContextType.EXTENDED ,這意味著它可以承受多個請求。

什么定義了EntityManager vs Transaction關系?

這實際上是應用程序開發人員的選擇,但是使用JPA實體管理器的最常見方法是使用“每個應用程序事務的實體管理器”模式。 這是注入實體管理器的最常見方法:

@PersistenceContextprivate EntityManager em;

在這里,默認情況下,我們處于“每個事務實體管理器”模式。 在這種模式下,如果我們在@Transactional方法內使用此實體管理器,則該方法將在單個數據庫事務中運行。

@PersistenceContext如何工作?

想到的一個問題是,鑒于實體管理器的生命周期如此短,并且每個請求通常有多個實體,因此@PersistenceContext如何在容器啟動時僅注入一次實體管理器。

答案是:它不能: EntityManager是一個接口,注入到bean中的不是實體管理器本身,而是上下文感知的代理 ,它將在運行時委派給具體的實體管理器。

通常,用于代理的具體類是SharedEntityManagerInvocationHandler ,可以在調試器的幫助下進行確認。

@Transactional如何工作?

實現EntityManager的持久性上下文代理不是使聲明式事務管理工作所需的唯一組件。 實際上需要三個獨立的組件:

  • EntityManager代理本身
  • 交易方面
  • 交易經理

讓我們逐一檢查一下,看看它們如何相互作用。

交易方面

事務方面是在注釋的業務方法之前和之后都被調用的“周圍”方面。 實現方面的具體類是TransactionInterceptor 。

事務方面有兩個主要職責:

  • 在“之前”時刻,該方面提供了一個掛鉤點,用于確定要調用的業務方法是否應在正在進行的數據庫事務范圍內運行,或者是否應該啟動新的單獨事務。
  • 在“之后”時刻,方面需要確定是應該提交事務,回滾事務還是保持運行。

在“之前”時刻,事務方面本身不包含任何決策邏輯,如果需要,則啟動新事務的決策將委托給事務管理器。

交易經理

交易經理需要提供以下兩個問題的答案:

  • 是否應該創建一個新的實體管理器?
  • 是否應該啟動新的數據庫事務?

這需要在調用事務方面“之前”邏輯時確定。 交易經理將根據以下內容做出決定:

  • 一項交易是否已經進行的事實
  • 事務方法的傳播屬性(例如, REQUIRES_NEW始終啟動新事務)

如果交易經理決定創建新交易,則它將:

  • 創建一個新的實體經理
  • 將實體管理器綁定到當前線程
  • 從數據庫連接池中獲取連接
  • 將連接綁定到當前線程

實體管理器和連接都使用ThreadLocal變量綁定到當前線程。

它們在事務運行時存儲在線程中,并且當不再需要它們時,由事務管理器來清理它們。

程序中需要當前實體管理器或連接的任何部分都可以從線程中檢索它們。 正是這樣做的一個程序組件是EntityManager代理。

EntityManager代理

最后一步是EntityManager代理(我們之前已經介紹過)。 以業務方法為例
entityManager.persist() ,此調用未直接調用實體管理器。

相反,業務方法調用代理,該代理從線程(事務管理器放置在該線程中)中檢索當前實體管理器。

現在知道了@Transactional機制的哪些移動部分,讓我們@Transactional這項工作所需的常規Spring配置。

全部放在一起

讓我們研究一下如何設置使事務注釋正確工作所需的三個組件。 我們首先定義實體管理器工廠。

這將允許通過持久性上下文注釋注入Entity Manager代理:

@Configurationpublic class EntityManagerFactoriesConfiguration {@Autowiredprivate DataSource dataSource;@Bean(name = "entityManagerFactory")public LocalContainerEntityManagerFactoryBean emf() {LocalContainerEntityManagerFactoryBean emf = ...emf.setDataSource(dataSource);emf.setPackagesToScan(new String[] {"your.package"});emf.setJpaVendorAdapter(new HibernateJpaVendorAdapter());return emf;}}

下一步是配置事務管理器,并將事務方面應用于@Transactional注釋的類:

@Configuration@EnableTransactionManagementpublic class TransactionManagersConfig {@AutowiredEntityManagerFactory emf;@Autowiredprivate DataSource dataSource;@Bean(name = "transactionManager")public PlatformTransactionManager transactionManager() {JpaTransactionManager tm = new JpaTransactionManager();tm.setEntityManagerFactory(emf);tm.setDataSource(dataSource);return tm;}}

注釋@EnableTransactionManagement告訴Spring帶有@Transactional注釋的類應使用Transactional Aspect包裝。 這樣,@ @Transactional現在可以使用了。

結論

Spring聲明式事務管理機制非常強大,但是很容易被濫用或錯誤配置。

在機制無法正常工作或無法正常工作的情況下進行故障排除時,了解其內部工作方式將很有幫助。

要牢記的最重要的一點是,實際上有兩個概念需要考慮:數據庫事務和持久性上下文,每個都有其自身不容易顯現的生命周期。

將來的帖子將討論事務注釋的最常見陷阱以及如何避免它們。

翻譯自: https://www.javacodegeeks.com/2014/06/how-does-spring-transactional-really-work.html

總結

以上是生活随笔為你收集整理的Spring @Transactional实际如何工作?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。