Spring事務完全解析

事務是什么围俘?了解事務的原理嗎簿寂?說下Spring的事務原理常遂,能自己實現(xiàn)Spring事務原理嗎克胳?先自我檢測下這些知識掌握了嗎漠另。那么接下來一起看下與Spring相關的事務

概念

事務具有ACID特性笆搓。

是指作為單個邏輯工作單元執(zhí)行的一系列操作砚作,要么完全地執(zhí)行葫录,要么完全地不執(zhí)行米同。

Spring事務的底層依賴MySQL的事務少孝,代碼層面上利用AOP實現(xiàn)稍走。MySQL的事務有隔離級別的概念婿脸,只有InnoDB有事務柄驻,并且實現(xiàn)方式是利用undo log和redo log抑钟。

AOP方面野哭,有連接點,切點蛔溃,增強揪利,目標疟位,織入绍撞。參考Spring AOP入門章贞,Spring則是在代碼層面執(zhí)行事務的時候使用TransactionInceptor進行攔截鸭限,然后處理败京。

系統(tǒng)解析Spring事務原理文章:

代碼

  1. 在AopConfigUtils可以看到具體會生成什么類型的AutoProxyCreator赡麦,這幾個都是beanPostProcessor帕识,在Bean創(chuàng)建之后對Bean的實例進行自定義處理泛粹。如果使用了@EnableTransactionManagement,經(jīng)過一些配置這次生成的是InfrastructureAdvisorAutoProxyCreator渡冻,具體如何生成這個類的點進去@EnableTransactionManagement里面即可戚扳。
image
EnableTransactionManagement
-> @Import(TransactionManagementConfigurationSelector.class)
-> return new String[] {AutoProxyRegistrar.class.getName(),
                        ProxyTransactionManagementConfiguration.class.getName()};
-> AutoProxyRegistrar.registerBeanDefinitions中
-> 創(chuàng)建InfrastructureAdvisorAutoProxyCreator
image
  1. 在Bean的生命周期中,Bean創(chuàng)建完成調(diào)用創(chuàng)建InfrastructureAdvisorAutoProxyCreator.postProcessAfterInitialization方法族吻。

    另外AbstractAutowireCapableBeanFactory.initializeBean方法也值得一看

    獲取Bean的Advice帽借,如果有Advice(增強的話),創(chuàng)建bean的動態(tài)代理超歌。創(chuàng)建動態(tài)代理都是Spring AOP做的事情了砍艾,根據(jù)設置就是創(chuàng)建JDK動態(tài)代理和CGLib代理了,我們項目默認都是使用CGLib動態(tài)代理(proxyTargetClass=true即可),只說下CGlib的動態(tài)代理,主要利用了Enhancer類

image

? 這里有Enhacer用法Cglib的使用方法(1)--Enhancer

?

? 攔截接口intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy)有我們根據(jù)條件進行是否要攔截的數(shù)據(jù),根據(jù)參數(shù)就可以判斷。

?

  1. 可以跟進去DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice方法中看

    PointcutAdvisor為BeanFactoryTransactionAttributeSourceAdvisor
    MethodMatcher為TransactionAttributeSourcePointcut
    
image

得到的攔截器為事務攔截器惜犀,既然是事務攔截器莉御,那么可以跟上之前的分析了琅关。

Spring事務原理分析

  1. 我們接著看為什么獲取的攔截器是MethodInterceptor新症。在MethodMatcher.match中有AdvisorAdapter
image

而Advice是advisor中的侯繁,advisor是BeanFactoryTransactionAttributeSourceAdvisor

  • 一種在TransactionProxyFactoryBean中默認的TransactionIntercetor
image
  • 在默認的@EnableTransactionManagement注解中粹懒,將BeanFactoryTransactionAttributeSourceAdvisor的advice設置為TransactionIntercetor弓颈,這一步的注解生效搬瑰,我們第一步就已經(jīng)講過了翼悴。
image
  1. 方法是如何匹配的,TransactionAttributeSourcePointcut中matches方法沾谜,調(diào)用TransactionAttributeSource屬性判斷是否有method的屬性
image

然后調(diào)用computeTransactionAttribute(method, targetClass)荆秦,判斷是否有事務屬性

AbstractFallbackTransactionAttributeSource.computeTransactionAttribute
--> AnnotationTransactionAttributeSource.determineTransactionAttribute 獲取方法屬性
--> 獲取到TransactionAttribute瓤介,然后返回
  1. 到現(xiàn)在我們基本上解釋了,Spring的事務攔截器是如何生效的,攔截器什么時候設置的填抬,事務方法是如何匹配的。

事務不生效

  • private方法不會生效揍堰,JDK中必須是接口式塌,接口中不可能有private方法链沼,而私有方法子類無法方法括勺,也不會生效
  • CGLib代理的時候,final方法不會生效,拋NullPointException
  • protect方法的話错负,默認是只允許public方法油航。
image

最后一個就是在當前的bean中非事務方法調(diào)用事務方法為什么不生效函筋?

public int save(String name, int age) throws Exception {
        insert(name, age);
        return 1;
    }
    @Transactional
    public void insert(String name, int age){
        jdbcTemplate.update("insert into user(id,name,age)values(1,'"+name+"',"+age+")");
        jdbcTemplate.update("insert into user(id,name,age)values(2,'"+name+"',"+age+")");
        jdbcTemplate.update("insert into user(id,name,age)values(1,'"+name+"',"+age+")");
    }

答:

經(jīng)過最終驗證欲芹,得出如下結(jié)論:

如果先調(diào)用的save方法牵囤,在進行方法攔截的時候,方法攔截器首先獲取當前動態(tài)代理的對象所代理的原始對象滞伟。

image

比如FirstApp生成的動態(tài)代理名稱為FirstApp$CGlibxxx揭鳞,這個時候通過getTarget獲取的對象即為FirstApp的實例。

接下來如果判斷當前的方法比如save方法沒有Advice(增強)梆奈,則直接調(diào)用原對象的方法野崇,即這個時候調(diào)用的是FirstApp.save方法。而不是FirstApp$CGLibxxx的save方法亩钟∨依妫可以跟代碼。

最后

Spring事務這塊清酥,如果認真看我寫的文章扶镀,相信你會收獲不少

參考

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市焰轻,隨后出現(xiàn)的幾起案子臭觉,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蝠筑,死亡現(xiàn)場離奇詭異狞膘,居然都是意外死亡,警方通過查閱死者的電腦和手機什乙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門挽封,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人臣镣,你說我怎么就攤上這事辅愿。” “怎么了忆某?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵点待,是天一觀的道長。 經(jīng)常有香客問我褒繁,道長,這世上最難降的妖魔是什么馍忽? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任棒坏,我火速辦了婚禮,結(jié)果婚禮上遭笋,老公的妹妹穿的比我還像新娘坝冕。我一直安慰自己,他們只是感情好瓦呼,可當我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布喂窟。 她就那樣靜靜地躺著,像睡著了一般央串。 火紅的嫁衣襯著肌膚如雪磨澡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天质和,我揣著相機與錄音稳摄,去河邊找鬼。 笑死饲宿,一個胖子當著我的面吹牛厦酬,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瘫想,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼仗阅,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了国夜?” 一聲冷哼從身側(cè)響起减噪,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后旋廷,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鸠按,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年饶碘,在試婚紗的時候發(fā)現(xiàn)自己被綠了目尖。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡扎运,死狀恐怖瑟曲,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情豪治,我是刑警寧澤洞拨,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站负拟,受9級特大地震影響烦衣,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜掩浙,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一花吟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧厨姚,春花似錦衅澈、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至拭抬,卻和暖如春部默,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背造虎。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工甩牺, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人累奈。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓贬派,卻偏偏與公主長得像,于是被迫代替她去往敵國和親澎媒。 傳聞我的和親對象是個殘疾皇子搞乏,可洞房花燭夜當晚...
    茶點故事閱讀 44,927評論 2 355

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

  • IOC和DI是什么? Spring IOC 的理解戒努,其初始化過程请敦? BeanFactory 和 FactoryBe...
    justlpf閱讀 3,474評論 1 21
  • 什么是Spring Spring是一個開源的Java EE開發(fā)框架镐躲。Spring框架的核心功能可以應用在任何Jav...
    jemmm閱讀 16,464評論 1 133
  • 概述 Spring是什么? Spring是一個開源框架侍筛,為了解決企業(yè)應用開發(fā)的復雜性而創(chuàng)建的萤皂,但是現(xiàn)在已經(jīng)不止于企...
    瑯筑閱讀 1,168評論 2 8
  • Spring Framework 現(xiàn)在幾乎已成為 Java Web 開發(fā)的標配框架。那么匣椰,作為 Java 程序員裆熙,...
    fad2aa506f5e閱讀 393評論 0 0
  • 日子如流水般過著,波瀾不驚禽笑。 許多想法總是被扼殺在搖籃中或者斷送在前行的道路上入录,唯有刺繡,一直堅持著佳镜,這也許就是真...
    葉樣悠閱讀 935評論 7 3