Spring研究筆記------事務(wù)探究

? ? ? 最近看了比較多Spring的東西,腦中概念知識比較雜亂链烈,借助周六周天的閑暇時間厉斟,寫一些內(nèi)容,梳理一下自己腦中的概念强衡,也以此作為記錄擦秽,希望自己以后能夠方便查閱,也希望能夠?qū)Ω魑豢垂儆兴鶐椭?/p>

? ? 第一個Spring相關(guān)主題是Spring的事務(wù)管理食侮,借助官方文檔的一句話,Spring提供了一致的事物管理抽象模型目胡,能夠讓大家在不同的事務(wù)API(JTA锯七、JDBC、Hibernate誉己、JPA眉尸、JDO等)之間有一致的編程體驗,Spring提供了聲明式事務(wù)管理和編程事務(wù)管理兩種事務(wù)管理方式巨双,前者借鑒了EJB CMT中事務(wù)管理方式噪猾,后者則簡化了JTA的事務(wù)異常編程模型,從這個角度來看筑累,Spring事務(wù)提供了全面簡潔的一致性事務(wù)管理方案袱蜡。

熟悉Java EE編程的人應(yīng)該知道,事務(wù)分為全局(global)和本地(local)兩種事務(wù)慢宗;全局事務(wù)提供了在多個事務(wù)源之間操作保證原子性的能力坪蚁,典型的事務(wù)源是數(shù)據(jù)庫,在一些企業(yè)集成領(lǐng)域還包括MQ等中間件镜沽,在Java EE體系中通過JTA來對全局事務(wù)提供支持敏晤,事務(wù)管理功能由應(yīng)用服務(wù)器提供支持,在實際操作時需要通過JNDI進(jìn)行事務(wù)對象的引用缅茉,這就存在兩種耦合綁定嘴脾,特定查找協(xié)議和特定應(yīng)用容器綁定,這是不是不良的組織形式要看應(yīng)用的需求蔬墩,但在大多數(shù)時候译打,大多數(shù)應(yīng)用為了獲取全局事務(wù)的能力而付出這種耦合的代價都是比較不合算的耗拓;本地事務(wù)是資源特定的,例如使用JDBC connection進(jìn)行的事務(wù)操作扶平,本地事務(wù)中的事物管理功能是應(yīng)用程序進(jìn)行控制的帆离,非容器托管,因此其能擺脫容器綁定的副作用结澄,但其局限性也很明顯哥谷,因為是資源特定的,其不能支持跨事務(wù)源的操作麻献,所幸我們大部分應(yīng)用都沒有跨事務(wù)源的需求们妥,本地事務(wù)在這種情況下比較適用;關(guān)于全局事務(wù)這里多補(bǔ)充一點(diǎn)勉吻,因為分布式事務(wù)本身的復(fù)雜性监婶,其比較重量級,考慮的事務(wù)模型可能也比較復(fù)雜齿桃,除非必須使用惑惶,否則還是敬而遠(yuǎn)之為好,即使因為水平擴(kuò)展短纵、高可用带污、負(fù)載均衡等需求而需要添置額外的事務(wù)源,也應(yīng)該盡量避免香到,例如使用Oracle RAC鱼冀,將分布式事務(wù)的復(fù)雜性封裝在數(shù)據(jù)庫產(chǎn)品層面,簡化應(yīng)用級別的事務(wù)操作悠就;實際上千绪,全局事務(wù)操作不一定非需要綁定應(yīng)用容器,借助獨(dú)立的事務(wù)管理器如Atomikos Transactions 和?JOTM也能提供JTA全局事務(wù)的功能梗脾,當(dāng)然荸型,還是如上所述,并不推薦使用炸茧。

? ? Spring提供了一致的事務(wù)抽象帆疟,而這抽象的核心就是PlatformTransactionManager接口,接口定義如下


該接口有三個方法宇立,第一個方法根據(jù)TransationDefinition對象獲取事務(wù)(TransactionStatus)踪宠,TransationDefinition也是一個接口,定義如下


通過這個定義妈嘹,我們知道TransationDefinition提供了事務(wù)傳播策略以及事務(wù)隔離級別的常量定義柳琢,同時提供了默認(rèn)隔離和默認(rèn)事務(wù)超時的常量定義,方法上提供了獲取事務(wù)隔離級別、事務(wù)傳播策略柬脸、事務(wù)超時時間掠兄、是否只讀事務(wù)以及事務(wù)名稱信息宾巍,基本上事務(wù)的基本概念都包含在了這個接口定義中拜鹤;TransactionStatus提供了簡單的控制事務(wù)以及查詢事務(wù)狀態(tài)的方法丰包,定義如下


因為接口定義比較明了,這里不再展開贅述垦巴;PlatformTransactionManager接口是Spring事務(wù)管理的核心媳搪,其類級結(jié)構(gòu)如下


通過上面的結(jié)構(gòu)圖,我們看到Spring為每一種常用的具體的事務(wù)操作API提供了具體的實現(xiàn)骤宣,例如我們常用的基于純JDBC的DataSourceTransactionManager和常用ORM hibernate的HibernateTransactionManager秦爆,JTA API特供了通用的實現(xiàn)以及針對Weblogic、WebSphere應(yīng)用服務(wù)器提供的特定實現(xiàn)憔披;PlatformTransactionManager定義了基本的事務(wù)操作模型等限,而AbstractPlatformTransactionManager抽象類實現(xiàn)了該接口,該抽象類定義了一些所有具體實現(xiàn)類共有的屬性和方法芬膝,同時定義了統(tǒng)一的事務(wù)處理流程望门,這是設(shè)計模式模板模式非常經(jīng)典的應(yīng)用,因為該類方法定義較多锰霜,這里我們就不在貼出該類的定義筹误,我們來看看該類如何定義了統(tǒng)一的事務(wù)處理流程,該類實現(xiàn)了PlatformTransactionManager接口的commit方法锈遥,同時將該方法設(shè)為final纫事,使其子類不能夠重寫勘畔,commit方法如下:


該方法定義了基本的提交處理所灸,我們看到實際處理是processXXX等方法,processCommit部分代碼如下


我們看到這個方法負(fù)責(zé)了具體事務(wù)提交的相關(guān)操作炫七,最后實際提交操作是doCommit爬立,而doCommit為一個抽象方法,這就是該類給子類實現(xiàn)留下的“鉤子”万哪,具體的提交操作由子類來去實現(xiàn)侠驯,這是一個典型的模板模式應(yīng)用,接下來我們找一個具體子類來看看doCommit的實際操作奕巍,我們看看比較熟悉的HibernateTransactionManager吟策,doCommit如下:


很明顯,看到了Hibernate事務(wù)操作典型的用法的止,其他實現(xiàn)類似檩坚,這里我們不在贅述,大家可以自己看看。

? ? ? ? 關(guān)于具體的Spring事務(wù)配置匾委,雖然比較基礎(chǔ)拖叙,但我還是寫在這里吧,在事務(wù)配置過程中赂乐,我穿插著描述一些原理性的東西薯鳍,因為頭腦比較混亂,條理不清挨措,還望大家海涵挖滤。

事務(wù)管理配置的核心是各種具體PlatformTransactionManager的配置,其次就是各種事務(wù)管理器如何作用在具體操作方法上的切面配置运嗜,因為事務(wù)管理器到具體方法的切面配置都是一致的壶辜,這里我們給出各種PlatformTransactionManager的配置,最后在來一個具體的事務(wù)切面配置担租,這里我們提供DataSourceTransactionManager砸民、JtaTransactionManager以及HibernateTransactionManager的配置,關(guān)于用XML配置還是注解配置奋救,這里我們先提供XML的配置岭参,然后在后面給出一個完全注解的配置實例。

PlatformTransactionManager配置

1. DataSourceTransactionManager

首先需要配置JDBC的DataSource尝艘,畢竟這些本地事務(wù)是資源特定的嘛演侯,DataSource定義如下


接著就是事務(wù)管理器的配置,DataSourceTransactionManager定義如下


這里事務(wù)管理器就配置完了背亥,非常簡單秒际。

2.?JtaTransactionManager

JtaTransactionManager配置更為簡單,因為其是全局事務(wù)狡汉,為容器托管事務(wù)娄徊,其不需要知道特定的資源(DataSource),配置如下



但是注意JtaTransactionManager不需要知道DataSource盾戴,并不意味著不需要配置寄锐,Spring Data模塊對資源的操作還是需要DataSource的,在這種場景下DataSource由應(yīng)用容器托管尖啡,所以使用JNDI進(jìn)行查找引用橄仆,如下


3.HibernateTransactionManager

Hibernate的配置比較多一些,首先是配置DataSource衅斩,和1中一致盆顾,這里不再贅述,接著就是SessionFactory的配置畏梆,配置如下



注意這里的配置比較老您宪,如果使用基于注解的實體配置惫搏,請將mappingResources替換為


接著就是HibernateTransactionManager的配置了,配置如下


注意實際的持久化技術(shù)例如JDBC蚕涤、JPA筐赔、JDO、Hibernate等和實際使用的事務(wù)管理器之間的區(qū)別揖铜,其沒有必要一一對應(yīng)茴丰,在使用JDBC時可以使用JTA全局事務(wù)管理器,同樣天吓,使用Hibernate也可以贿肩,只需將最后一步的事務(wù)管理器替換為JtaTransactionManager即可。

事務(wù)管理器到特定方法配置

? ? 接下來就是具體事務(wù)管理器如何作用在具體方法上的配置了龄寞,不過在這之前我們描述一下這個使用背景汰规,如前所述,Spring提供了兩種事務(wù)管理方式物邑,一種是聲明式事務(wù)管理(Declarative transaction management)溜哮,另一種則是編程式事務(wù)管理(Programmatic transaction management),這兩種方式顯然聲明式比較簡單色解,而在事務(wù)管理需求比較少的時候茂嗓,想比較聲明式比較繁瑣的配置,編程式則比較簡單科阎,這里大家根據(jù)自己的需求進(jìn)行選擇述吸,Spring官方推薦使用聲明式事務(wù)管理,后面的論述也會分別給出聲明式事務(wù)和編程式事務(wù)相關(guān)主題锣笨。

聲明式配置

? ? 聲明式事務(wù)管理的基本原理是利用在Spring中應(yīng)用比較廣泛的面向切面編程(AOP)蝌矛,通過將事務(wù)處理放在切面對象中來進(jìn)行一致性的管理,減少冗余代碼错英,提升簡潔性入撒,原理圖大致如下


其中的AOP proxy,Spring定義了TransactionInterceptor類走趋,該類結(jié)構(gòu)如下


通過這個結(jié)構(gòu)衅金,我們看到實際的方法都在TransactionInterceptor的父類TransactionAspectSupport中噪伊,TransactionInterceptor的關(guān)鍵方法是invoke方法簿煌,而這個方法內(nèi)部調(diào)用了父類的invokeWithinTransaction方法,這是這里事務(wù)處理的核心鉴吹,invokeWithinTransaction方法片段如下


這看起來是一個典型的切面代理方法姨伟,我們按照順序講下主要流程,首先270行獲取該方法的事務(wù)屬性豆励,這些屬性包括事務(wù)隔離級別夺荒、事務(wù)傳播策略瞒渠、只讀、回滾等屬性信息技扼,然后271行獲取平臺事務(wù)管理器伍玖,因為Spring支持多事務(wù)管理器特性,這里需要配合實際配置來決定具體的事務(wù)管理器剿吻,注意276行窍箍,這一行獲取了事務(wù)信息,同時又在必要情況下開啟了事務(wù)丽旅,后面281行是具體方法執(zhí)行椰棘,291行提交事務(wù)。

? ? 上面說了些原理榄笙,這里給出聲明式事務(wù)的一些具體應(yīng)用配置邪狞,在Spring中聲明式事務(wù)大體有兩種用法,一種是純粹的切面配置茅撞,一種是基于@Transactional的注解配置帆卓,這里都會給出具體應(yīng)用實例。

? 1.基于切面的配置

? ? 基于界面的配置比較簡單米丘,核心是Transaction 的Advice的配置鳞疲,然后將這Advice配置在具體pointcut上就可以了,我們先看看Advice的配置蠕蚜,配置實例如下:


如上尚洽,這里的配置比較清晰明了,引用具體的事務(wù)管理器(如果事務(wù)管理器名稱為transactionManager靶累,那么可以不需要明確引用事務(wù)管理器)腺毫,然后通配符匹配特定方法,配置特定事務(wù)屬性挣柬;配置完Advice潮酒,接下來是將Advice關(guān)聯(lián)到pointcut的配置,如下


這里的配置比較簡單邪蛔,不在贅述

關(guān)于事務(wù)屬性的配置急黎,可配置屬性如下


除方法名之外,其他屬性都是可選的侧到,根據(jù)具體的應(yīng)用場景進(jìn)行定制勃教,事務(wù)傳播策略定義了不同事務(wù)的存在關(guān)系,可選屬性列表如下(注意Spring事務(wù)概念中邏輯事務(wù)和物理事務(wù)的區(qū)別匠抗,物理事務(wù)就是指數(shù)據(jù)庫層面的事務(wù)故源,而邏輯事務(wù)是應(yīng)用層面的,可以具有更豐富的行為特性汞贸,Spirng中的事務(wù)就是特指邏輯事務(wù)绳军,要注意)


事務(wù)隔離級別這個屬性是數(shù)據(jù)庫層面的印机,可選屬性列表如下


具體這些問題以及每個隔離級別的具體特征有機(jī)會在進(jìn)行敘述吧,不然太多了门驾,這里注意不同的數(shù)據(jù)庫對不同隔離級別支持是不同的射赛,例如Oracle只能支持讀提交和序列化,不可重復(fù)讀的問題通過額外的樂觀鎖實現(xiàn)奶是,其中存在只讀事務(wù)咒劲,隔離級別實際是序列化,在配置事務(wù)只讀時要注意這里的特性诫隅;Mysql支持比較豐富腐魂,但其可重復(fù)讀能夠解決部分幻讀問題,這是與其實現(xiàn)有關(guān)的逐纬,等有機(jī)會把它展開敘述蛔屹,一般應(yīng)用場景下設(shè)置讀提交就能滿足要求,讀未提交隔離過低豁生,而其他兩個隔離級別又太重量級兔毒,使用的話會嚴(yán)重降低應(yīng)用性能,對于一些并發(fā)問題的容忍性甸箱,第一更新丟失育叁、臟讀、不可重復(fù)讀(特殊場景為第二更新丟失)是不能容忍的芍殖,這里可以使用讀提交隔離級別+樂觀鎖來屏蔽第二更新丟失的問題豪嗽,這是一個權(quán)衡場景需要和性能情況下做出的綜合性方案。

事務(wù)超時設(shè)置可以根據(jù)需要設(shè)置豌骏,一般情況下龟梦,為了防止數(shù)據(jù)庫鎖阻塞,所有方法都應(yīng)該有事務(wù)超時時間窃躲。

只讀事務(wù)設(shè)置注意其性能優(yōu)化的價值计贰,一般情況下,只讀操作可能都不需要事務(wù)蒂窒,這時候降低事務(wù)隔離級別或者干脆不要事務(wù)都能夠提升應(yīng)用性能躁倒。

事務(wù)異常回滾洒琢,關(guān)于受檢異常和非受檢異常的爭論這里就不在論述了秧秉,Spring事務(wù)采用了JTA的慣例,默認(rèn)情況下只用運(yùn)行時異常及其子類會導(dǎo)致事務(wù)回滾纬凤,受檢異常不會導(dǎo)致事務(wù)回滾福贞,后面兩個選項就是關(guān)于回滾與不回滾異常設(shè)置的撩嚼,這里可以根據(jù)需要進(jìn)行設(shè)置停士。

2.基于@Transactional的事務(wù)管理

說完了切面設(shè)置的事務(wù)管理挖帘,這里說一下基于@Transactional的事務(wù)管理,我們看下該注解的一些定義恋技,如下


通過上面的定義拇舀,我們知道這個注解可以放在類上和特定方法(只能為public方法,protected蜻底、private骄崩、package-visible都不可以)上,放在類上的話薄辅,該類所有的public方法都有了事務(wù)要拂,放在特定方法上可以定制這個方法執(zhí)行的事務(wù)屬性,為了啟用這種注解式的事務(wù)管理方式站楚,需要在xml中添加如下信息


這時候就可以把之前事務(wù)配置中切面的部分刪掉了脱惰,關(guān)于該注解上的屬性,因為和上面切面形式中類似窿春,這里就不在贅述了

上面的配置還是基于XML的拉一,這里給出一個完全基于注解的實例

注解配置類如下



這里開啟bean掃描,開啟基于@Transactional的事務(wù)管理

其中的一些Bean定義旧乞,DataSource


SessionFactory



編程式事務(wù)管理

? ? 說完了聲明式的事務(wù)管理蔚润,接下來講講編程式事務(wù)管理,Spring提供了兩種編程方式尺栖,一種是使用TransactionTemplate嫡纠,一種是直接使用具體PlatformTransactionManager,官方推薦第一種方式延赌,接下來我們分別進(jìn)行敘述货徙。

1. 使用TransactionTemplate

TransactionTemplate采用一種回調(diào)的方式將要執(zhí)行方法包含在事務(wù)中,其初始化需要指定特定的事務(wù)管理器皮胡,實際使用代碼片段如下


2.使用PlatformTransactionManager

這個比較簡單痴颊,關(guān)鍵是定義TransactionDefinition,代碼如下


代碼很清晰明了屡贺,這里就不在贅述了蠢棱。

寫不下去了,算是做了一次梳理吧甩栈,有時間在進(jìn)行詳細(xì)敘述泻仙。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市量没,隨后出現(xiàn)的幾起案子玉转,更是在濱河造成了極大的恐慌,老刑警劉巖殴蹄,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件究抓,死亡現(xiàn)場離奇詭異猾担,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)刺下,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門绑嘹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人橘茉,你說我怎么就攤上這事工腋。” “怎么了畅卓?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵擅腰,是天一觀的道長。 經(jīng)常有香客問我翁潘,道長惕鼓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任唐础,我火速辦了婚禮箱歧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘一膨。我一直安慰自己呀邢,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布豹绪。 她就那樣靜靜地躺著价淌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瞒津。 梳的紋絲不亂的頭發(fā)上蝉衣,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機(jī)與錄音巷蚪,去河邊找鬼病毡。 笑死,一個胖子當(dāng)著我的面吹牛屁柏,可吹牛的內(nèi)容都是我干的啦膜。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼淌喻,長吁一口氣:“原來是場噩夢啊……” “哼僧家!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起裸删,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤八拱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肌稻,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡清蚀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了灯萍。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片轧铁。...
    茶點(diǎn)故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡每聪,死狀恐怖旦棉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情药薯,我是刑警寧澤绑洛,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站童本,受9級特大地震影響真屯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜穷娱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一绑蔫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧泵额,春花似錦配深、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至羞秤,卻和暖如春缸托,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背瘾蛋。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工俐镐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人哺哼。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓京革,卻偏偏與公主長得像,于是被迫代替她去往敵國和親幸斥。 傳聞我的和親對象是個殘疾皇子匹摇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,809評論 6 342
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)甲葬,斷路器廊勃,智...
    卡卡羅2017閱讀 134,654評論 18 139
  • 這部分的參考文檔涉及數(shù)據(jù)訪問和數(shù)據(jù)訪問層和業(yè)務(wù)或服務(wù)層之間的交互。 Spring的綜合事務(wù)管理支持覆蓋很多細(xì)節(jié),然...
    竹天亮閱讀 1,038評論 0 0
  • 5.Spring的事務(wù) 通常情況下坡垫,J2EE有2種事務(wù)管理方式:全局事務(wù)和本地事務(wù)梭灿,2種事務(wù)都比較明顯的缺陷。 全...
    FTOLsXD閱讀 1,508評論 0 8
  • 概率論考試真是叫人心累冰悠,不想學(xué)習(xí)的我已經(jīng)快放棄了堡妒,只求及格。 我復(fù)習(xí)的程度基本上考試是可以及格的溉卓。因為我的要求是及...
    一條那啥閱讀 135評論 0 0