亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

Spring @Transactional工作原理詳解

2024-07-13 10:15:43
字體:
來源:轉載
供稿:網友

本文將深入研究Spring的事務管理。主要介紹@Transactional在底層是如何工作的。之后的文章將介紹:

propagation(事務傳播)和isolation(隔離性)等屬性的使用

事務使用的陷阱有哪些以及如何避免

JPA和事務管理

很重要的一點是JPA本身并不提供任何類型的聲明式事務管理。如果在依賴注入容器之外使用JPA,事務處理必須由開發人員編程實現。

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

這種方式的事務管理使事務范圍可以在代碼中很清晰地表達出來,但它有以下缺點:

容易出現重復代碼和錯誤

任何錯誤可能產生較大的影響

錯誤難以調試和復現

降低了代碼庫的可讀性

如果該方法調用了其他的事務方法如何處理呢?

使用Spring @Transactional

使用Spring @Transactional,上面的代碼就簡化為:

@Transactional   publicvoid businessLogic() {     ... use entity manager inside a transaction ...   } 

代碼更加簡潔,可讀性更好,也是目前Spring中事務處理的推薦方式。

通過使用@Transactional,事務傳播等很多重要方面可以自動處理。這種情況下如果businessLogic()調用了其他事務方法,該方法將根據選項確定如何加入正在運行事務。

這個強大機制的一個潛在缺點是它隱藏了底層的運行,當它不能正常工作時很難調試。

@Transactional含義

關于@Transactional,關鍵點之一是要考慮兩個獨立的概念,它們都有各自的范圍和生命周期:

persistence context(持久化上下文)

database transaction(事務)

@Transactional本身定義了單個事務的范圍。這個事務在persistence context的范圍內。

JPA中的持久化上下文是EntityManager,內部實現使用了Hibernate Session(使用Hibernate作為持久化provider)。

持久化上下文僅僅是一個同步對象,它記錄了有限集合的Java對象的狀態,并且保證這些對象的變化最終持久化到數據庫。

這是與單個事務非常不同的概念。一個Entity Manager可以跨越多個事務使用,而且的確是這樣使用的。

EntityManager何時跨越多個事務?

最常見的情況是應用使用Open Session In View模式處理懶初始化異常時,之前的文章介紹過這種做法的優勢和劣勢。

這種情況下視圖層運行的多個查詢處于獨立的事務中,而不是單事務的業務邏輯,但這些查詢由相同的entity manager管理。

另一種情況是開發人員將持久化上下文標記為PersistenceContextType.EXTENDED,這表示它能夠響應多個請求。

如何定義EntityManager和Transaction之間的關系?

這由應用開發者來選擇,但是JPA Entity Manager最常用的方式是“Entity Manager per application transaction”(每個事務都有自己的實體管理器)模式。entity manager注入的常用方法是:

@PersistenceContext   privateEntityManager em; 

這里默認為“Entity Manager per transaction”模式。這種模式下如果在@Transactional方法內部使用該Entity Manager,那么該方法將在單一事務中運行。

@PersistenceContext如何工作?

隨之而來的問題就是@PersistenceContext如何僅在容器啟動時注入entity manager,假定entity manager生命周期很短暫,而且每次請求需要多個entity manager。

答案是它不能:EntityManager是一個接口,注入到spring bean中的不是entity manager本身,而是在運行時代理具體entity manager的context aware proxy(上下文感知代理)。

通常用于代理的具體類為SharedEntityManagerInvocationHandler,借助調試器可以確認這一點。

那么@Transactional如何工作?

實現了EntityManager接口的持久化上下文代理并不是聲明式事務管理的唯一部分,事實上包含三個組成部分:

EntityManager Proxy本身

事務的切面

事務管理器

看一下這三部分以及它們之間的相互作用。

事務的切面

事務的切面是一個“around(環繞)”切面,在注解的業務方法前后都可以被調用。實現切面的具體類是TransactionInterceptor。

事務的切面有兩個主要職責:

在'before'時,切面提供一個調用點,來決定被調用業務方法應該在正在進行事務的范圍內運行,還是開始一個新的獨立事務。

在'after'時,切面需要確定事務被提交,回滾或者繼續運行。

在'before'時,事務切面自身不包含任何決策邏輯,是否開始新事務的決策委派給事務管理器完成。

事務管理器

事務管理器需要解決下面兩個問題:

新的Entity Manager是否應該被創建?

是否應該開始新的事務?

這些需要事務切面'before'邏輯被調用時決定。事務管理器的決策基于以下兩點:

事務是否正在進行

事務方法的propagation屬性(比如REQUIRES_NEW總要開始新事務)

如果事務管理器確定要創建新事務,那么將:

1.創建一個新的entity manager

2.entity manager綁定到當前線程

3.從數據庫連接池中獲取連接

4.將連接綁定到當前線程

使用ThreadLocal變量將entity manager和數據庫連接都綁定到當前線程。

事務運行時他們存儲在線程中,當它們不再被使用時,事務管理器決定是否將他們清除。

程序的任何部分如果需要當前的entity manager和數據庫連接都可以從線程中獲取。

EntityManager proxy

EntityManager proxy(前面已經介紹過)就是謎題的最后一部分。當業務方法調用entityManager.persist()時,這不是由entity manager直接調用的。

而是業務方法調用代理,代理從線程獲取當前的entity manager,前面介紹過事務管理器將entity manager綁定到線程。

了解了@Transactional機制的各個部分,我們來看一下實現它的常用Spring配置。

整合三個部分

如何將三個部分組合起來使事務注解可以正確地發揮作用呢?首先定義entity manager工廠。

這樣就可以通過持久化上下文注解注入Entity Manager proxy。

@Configuration   publicclass EntityManagerFactoriesConfiguration {	@Autowired 	    privateDataSource dataSource;	@Bean(name = "entityManagerFactory") 	    publicLocalContainerEntityManagerFactoryBean emf() {		LocalContainerEntityManagerFactoryBean emf = ... 		      emf.setDataSource(dataSource);		emf.setPackagesToScan( 		        newString[] {			"your.package"		}		);		emf.setJpaVendorAdapter( 		        newHibernateJpaVendorAdapter());		returnemf;	}}

下一步實現配置事務管理器和在@Transactional注解的類中應用事務的切面。

@Configuration   @EnableTransactionManagement   publicclass TransactionManagersConfig {	@Autowired 	    EntityManagerFactory emf;	@Autowired 	    privateDataSource dataSource;	@Bean(name = "transactionManager") 	    publicPlatformTransactionManager transactionManager() {		JpaTransactionManager tm =  		        newJpaTransactionManager();		tm.setEntityManagerFactory(emf);		tm.setDataSource(dataSource);		returntm;	}}

注解@EnableTransactionManagement通知Spring,@Transactional注解的類被事務的切面包圍。這樣@Transactional就可以使用了。

總結

Spring聲明式事務管理機制非常強大,但它可能被誤用或者容易發生配置錯誤。

當這個機制不能正常工作或者未達到預期運行結果等問題出現時,理解它的內部工作情況是很有幫助的。

需要記住的最重要的一點是,要考慮到兩個概念:事務和持久化上下文,每個都有自己不可讀的明顯的生命周期。

以上就是本文關于Spring @Transactional工作原理詳解的全部內容,希望對大家有所幫助。感興趣的朋友可以繼續參閱本站其他相關專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美激情奇米色| 一本色道久久综合狠狠躁篇的优点| 在线观看欧美成人| 成人在线小视频| 欧美噜噜久久久xxx| 亚洲欧美中文日韩在线v日本| 亚洲欧洲自拍偷拍| 日韩hd视频在线观看| 国产精品极品在线| 国语自产精品视频在线看| 久久精品国产欧美亚洲人人爽| 日韩精品中文字幕在线| 欧美激情亚洲视频| 亚洲国产日韩一区| 亚洲精品电影在线观看| 国产精品久久久久久中文字| 在线免费观看羞羞视频一区二区| 亚洲自拍偷拍福利| 精品国产区一区二区三区在线观看| 国产美女扒开尿口久久久| 欧美日本啪啪无遮挡网站| 色综合老司机第九色激情| 久久久久久中文| 亚洲福利视频专区| 日韩精品视频在线免费观看| 中文字幕精品网| yw.139尤物在线精品视频| 国产亚洲精品高潮| 91高潮在线观看| 日韩精品在线电影| 亚洲欧美日韩国产精品| 亚洲自拍高清视频网站| 另类视频在线观看| 久久久久久国产精品美女| 中文字幕免费精品一区| 欧美午夜片在线免费观看| 国产精品夫妻激情| 国内精品久久久久久| 亚洲精品免费在线视频| 久久国产精品影片| 国产欧美一区二区三区久久| 奇米四色中文综合久久| 欧美一区二区色| 久久久久日韩精品久久久男男| 亚洲成人av资源网| 热99久久精品| 亚洲在线观看视频| 精品香蕉在线观看视频一| 国产一区欧美二区三区| 久青草国产97香蕉在线视频| 久久91亚洲精品中文字幕奶水| 欧美美女18p| 亚洲天堂男人天堂女人天堂| 亚洲日本欧美日韩高观看| 久久精品欧美视频| 欧美疯狂性受xxxxx另类| 国产日韩在线观看av| 亚洲欧美日韩中文在线制服| 亚洲老司机av| 2020国产精品视频| 欧美日韩国产丝袜另类| 国产精品扒开腿做爽爽爽视频| 国产精品久久久久77777| 97国产真实伦对白精彩视频8| 成人国产精品久久久| 中文字幕亚洲专区| 亚洲欧美日韩精品| 成人免费网站在线| 久久精品国产清自在天天线| 国产精品视频一区二区高潮| 国产成人高清激情视频在线观看| 国产一区二区三区免费视频| 亚洲欧美日韩另类| 尤物精品国产第一福利三区| 国产成人精品视频| 亚洲国产精品va在线| 亚洲国产精品久久精品怡红院| 亚洲人成网站在线播| 亚洲欧美日韩区| 久久久久久久久久亚洲| 久久精品91久久香蕉加勒比| 97久久国产精品| 欧美极品欧美精品欧美视频| 在线观看日韩视频| 欧洲中文字幕国产精品| 色樱桃影院亚洲精品影院| 亚洲一区二区三区乱码aⅴ| 亚洲欧美日韩国产中文专区| 久久久久久久久久久久av| 4438全国成人免费| 亚洲午夜性刺激影院| 91久久综合亚洲鲁鲁五月天| 欧美性猛交xxxxx免费看| 国产精品嫩草影院一区二区| 欧美日韩国产va另类| 亚洲成人1234| 日韩高清av一区二区三区| 国产精品美女www| 欧美超级免费视 在线| 国产精品日韩欧美综合| 亚洲成人av片| 欧美午夜片在线免费观看| 成人免费视频网址| 综合久久五月天| 国产噜噜噜噜久久久久久久久| 日韩国产激情在线| 亚洲美女激情视频| 欧美黑人一级爽快片淫片高清| 午夜精品视频在线| 日韩电影中文 亚洲精品乱码| 亚洲精品v天堂中文字幕| 欧美大片欧美激情性色a∨久久| 国产中文字幕日韩| 国产精品稀缺呦系列在线| 日韩精品视频免费| 久久精品视频va| 国产欧美日韩精品在线观看| 97视频免费在线看| 91亚洲va在线va天堂va国| 久久久精品2019中文字幕神马| 亚洲国产一区自拍| 国产一区二区三区久久精品| 午夜精品福利在线观看| 韩曰欧美视频免费观看| 国产专区精品视频| …久久精品99久久香蕉国产| 亚洲国产小视频在线观看| 国产亚洲欧美日韩美女| 国产精品久久久久国产a级| 国产日韩亚洲欧美| 午夜免费在线观看精品视频| 日韩视频永久免费观看| 国产精品一区二区三区久久久| 久热精品在线视频| 国产精品视频最多的网站| 国产亚洲一区二区精品| 久久久久久999| 日韩va亚洲va欧洲va国产| 91在线无精精品一区二区| 日本乱人伦a精品| 国产精品久久久久久久久久尿| 国产99久久精品一区二区 夜夜躁日日躁| 亚洲伊人一本大道中文字幕| 国产91精品视频在线观看| 91精品国产色综合| 91精品久久久久久久久久入口| 国产美女久久精品| 一本色道久久88精品综合| 丰满岳妇乱一区二区三区| 亚洲免费一在线| 日本久久久久久| 亚洲一区二区三区乱码aⅴ| 国模视频一区二区三区| 久久精品视频在线观看| 日韩美女免费观看| 国产精品91久久久久久| 91在线免费网站| 欧美日韩色婷婷| 亚洲丁香久久久| 国产69精品久久久久9999| 久久香蕉国产线看观看av| 国产成人精品日本亚洲专区61| 亚洲va国产va天堂va久久| 欧美激情视频在线|