摘要:和事務(wù)的關(guān)系關(guān)系型數(shù)據(jù)庫某些消息隊(duì)列等產(chǎn)品或中間件稱為事務(wù)性資源,因?yàn)樗鼈儽旧碇С质聞?wù),也能夠處理事務(wù)。事務(wù)的傳播特性,,,,,,強(qiáng)制要求要有一個(gè)物理事務(wù)。外圍事務(wù)不會(huì)被內(nèi)部事務(wù)的回滾狀態(tài)影響。不支持當(dāng)前事務(wù)。
Spring和事務(wù)的關(guān)系
關(guān)系型數(shù)據(jù)庫、某些消息隊(duì)列等產(chǎn)品或中間件稱為事務(wù)性資源,因?yàn)樗鼈儽旧碇С质聞?wù),也能夠處理事務(wù)。 Spring很顯然不是事務(wù)性資源,但是它可以管理事務(wù)性資源,所以Spring和事務(wù)之間是管理關(guān)系。 就像Jack Ma雖然不會(huì)寫代碼,但是他卻管理者一大批會(huì)寫代碼的碼農(nóng)。
Spring事務(wù)三要素
數(shù)據(jù)源:表示具體的事務(wù)性資源,是事務(wù)的真正處理者,如MySQL等。
事務(wù)管理器:像一個(gè)大管家,從整體上管理事務(wù)的處理過程,如打開、提交、回滾等。
事務(wù)應(yīng)用和屬性配置:像一個(gè)標(biāo)識(shí)符,表明哪些方法要參與事務(wù),如何參與事務(wù),以及一些相關(guān)屬性如隔離級(jí)別、超時(shí)時(shí)間等。
Spring事務(wù)的注解配置
把一個(gè)DataSource(如DruidDataSource)作為一個(gè)@Bean注冊到Spring容器中,配置好事務(wù)性資源。
把一個(gè)@EnableTransactionManagement注解放到一個(gè)@Configuration類上,配置好事務(wù)管理器,并啟用事務(wù)管理。
把一個(gè)@Transactional注解放到類上或方法上,可以設(shè)置注解的屬性,表明該方法按配置好的屬性參與到事務(wù)中。
事務(wù)注解的本質(zhì)
@Transactional這個(gè)注解僅僅是一些(和事務(wù)相關(guān)的)元數(shù)據(jù),在運(yùn)行時(shí)被事務(wù)基礎(chǔ)設(shè)施讀取消費(fèi),并使用這些元數(shù)據(jù)來配置bean的事務(wù)行為。
大致來說具有兩方面功能,一是表明該方法要參與事務(wù),二是配置相關(guān)屬性來定制事務(wù)的參與方式和運(yùn)行行為。
Spring聲明式事務(wù)實(shí)現(xiàn)原理
聲明式事務(wù)成為可能,主要得益于Spring AOP。使用一個(gè)事務(wù)攔截器,在方法調(diào)用的前后/周圍進(jìn)行事務(wù)性增強(qiáng)(advice),來驅(qū)動(dòng)事務(wù)完成。
如何回滾一個(gè)事務(wù)
就是在一個(gè)事務(wù)上下文中當(dāng)前正在執(zhí)行的代碼里拋出一個(gè)異常,事務(wù)基礎(chǔ)設(shè)施代碼會(huì)捕獲任何未處理的異常,并且做出決定是否標(biāo)記這個(gè)事務(wù)為回滾。
默認(rèn)回滾規(guī)則
默認(rèn)只把runtime, unchecked exceptions標(biāo)記為回滾,即RuntimeException及其子類,Error默認(rèn)也導(dǎo)致回滾。Checked exceptions默認(rèn)不導(dǎo)致回滾。這些規(guī)則和EJB是一樣的。
如何配置回滾異常
使用@Transactional注解的rollbackFor/rollbackForClassName屬性,可以精確配置導(dǎo)致回滾的異常類型,包括checked exceptions。
noRollbackFor/noRollbackForClassName屬性,可以配置不導(dǎo)致回滾的異常類型,當(dāng)遇到這樣的未處理異常時(shí),照樣提交相關(guān)事務(wù)。
事務(wù)注解在類/方法上
@Transactional注解既可以標(biāo)注在類上,也可以標(biāo)注在方法上。當(dāng)在類上時(shí),默認(rèn)應(yīng)用到類里的所有方法。如果此時(shí)方法上也標(biāo)注了,則方法上的優(yōu)先級(jí)高。
事務(wù)注解在類上的繼承性
@Transactional注解的作用可以傳播到子類,即如果父類標(biāo)了子類就不用標(biāo)了。但倒過來就不行了。
子類標(biāo)了,并不會(huì)傳到父類,所以父類方法不會(huì)有事務(wù)。父類方法需要在子類中重新聲明而參與到子類上的注解,這樣才會(huì)有事務(wù)。
事務(wù)注解在接口/類上
@Transactional注解可以用在接口上,也可以在類上。在接口上時(shí),必須使用基于接口的代理才行,即JDK動(dòng)態(tài)代理。
事實(shí)是Java的注解不能從接口繼承,如果你使用基于類的代理,即CGLIB,或基于織入方面,即AspectJ,事務(wù)設(shè)置不會(huì)被代理和織入基礎(chǔ)設(shè)施認(rèn)出來,目標(biāo)對(duì)象不會(huì)被包裝到一個(gè)事務(wù)代理中。
Spring團(tuán)隊(duì)建議注解標(biāo)注在類上而非接口上。
只在public方法上生效?
當(dāng)采用代理來實(shí)現(xiàn)事務(wù)時(shí),(注意是代理),@Transactional注解只能應(yīng)用在public方法上。當(dāng)標(biāo)記在protected、private、package-visible方法上時(shí),不會(huì)產(chǎn)生錯(cuò)誤,但也不會(huì)表現(xiàn)出為它指定的事務(wù)配置。可以認(rèn)為它作為一個(gè)普通的方法參與到一個(gè)public方法的事務(wù)中。
如果想在非public方法上生效,考慮使用AspectJ(織入方式)。
目標(biāo)類里的自我調(diào)用沒有事務(wù)?
在代理模式中(這是默認(rèn)的),只有從外部的方法調(diào)用進(jìn)入通過代理會(huì)被攔截,這意味著自我調(diào)用(實(shí)際就是,目標(biāo)對(duì)象中的一個(gè)方法調(diào)用目標(biāo)對(duì)象的另一個(gè)方法)在運(yùn)行時(shí)不會(huì)導(dǎo)致一個(gè)實(shí)際的事務(wù),即使被調(diào)用的方法標(biāo)有注解。
如果你希望自我調(diào)用也使用事務(wù)來包裝,考慮使用AspectJ的方式。在這種情況下,首先是沒有代理。相反,目標(biāo)類被織入(即它的字節(jié)碼被修改)來把@Transactional加入到運(yùn)行時(shí)行為,在任何種類的方法上都可以。
事務(wù)與線程
和JavaEE事務(wù)上下文一樣,Spring事務(wù)和一個(gè)線程的執(zhí)行相關(guān)聯(lián),底層是一個(gè)ThreadLocal
邏輯事務(wù)與物理事務(wù)
事務(wù)性資源實(shí)際打開的事務(wù)就是物理事務(wù),如數(shù)據(jù)庫的Connection打開的事務(wù)。Spring會(huì)為每個(gè)@Transactional方法創(chuàng)建一個(gè)事務(wù)范圍,可以理解為是邏輯事務(wù)。
在邏輯事務(wù)中,大范圍的事務(wù)稱為外圍事務(wù),小范圍的事務(wù)稱為內(nèi)部事務(wù),外圍事務(wù)可以包含內(nèi)部事務(wù),但在邏輯上是互相獨(dú)立的。每一個(gè)這樣的邏輯事務(wù)范圍,都能夠多帶帶地決定rollback-only狀態(tài)。
那么如何處理邏輯事務(wù)和物理事務(wù)之間的關(guān)聯(lián)關(guān)系呢,這就是傳播特性解決的問題。
事務(wù)的傳播特性
REQUIRED,SUPPORTS,MANDATORY,REQUIRES_NEW,NOT_SUPPORTED,NEVER,NESTED
REQUIRED
強(qiáng)制要求要有一個(gè)物理事務(wù)。如果沒有已經(jīng)存在的事務(wù),就專門打開一個(gè)事務(wù)用于當(dāng)前范圍。或者參與到一個(gè)已存在的更大范圍的外圍事務(wù)中。在相同的線程中,這是一種很好的默認(rèn)方式安排。(例如,一個(gè)service外觀/門面代理到若干個(gè)倉儲(chǔ)方法,所有底層資源必須參與到service級(jí)別的事務(wù)里)
在標(biāo)準(zhǔn)的REQUIRED行為情況下,所有這樣的邏輯事務(wù)范圍映射到同一個(gè)物理事務(wù)。因此,在內(nèi)部事務(wù)范圍設(shè)置了rollback-only標(biāo)記,確實(shí)會(huì)影響外圍事務(wù)進(jìn)行實(shí)際提交的機(jī)會(huì)。
注:默認(rèn),一個(gè)參與到外圍事務(wù)的事務(wù),會(huì)使用外圍事務(wù)的特性,安靜地忽略掉自己的隔離級(jí)別,超時(shí)值,只讀標(biāo)識(shí)等設(shè)置。當(dāng)然可以在事務(wù)管理器上設(shè)置validateExistingTransactions標(biāo)識(shí)為true,這樣當(dāng)你自己的事務(wù)和參與到的外圍事務(wù)設(shè)置不一樣時(shí)會(huì)被拒絕。
REQUIRES_NEW
與REQUIRED相比,總是使用一個(gè)獨(dú)立的物理事務(wù)用于每一個(gè)受影響的邏輯事務(wù)范圍,從來不參與到一個(gè)已存在的外圍事務(wù)范圍。這樣安排的話,底層的事務(wù)資源是不同的,因此,可以獨(dú)立地提交或回滾。外圍事務(wù)不會(huì)被內(nèi)部事務(wù)的回滾狀態(tài)影響。這樣一個(gè)獨(dú)立的內(nèi)部事務(wù)可以聲明自己的隔離級(jí)別,超時(shí)時(shí)間和只讀設(shè)置,并不繼承外圍事務(wù)的特性。
NESTED
使用同一個(gè)物理事務(wù),帶有多個(gè)保存點(diǎn),可以回滾到這些保存點(diǎn),可以認(rèn)為是部分回滾,這樣一個(gè)內(nèi)部事務(wù)范圍觸發(fā)了一個(gè)回滾,外圍事務(wù)能夠繼續(xù)這個(gè)物理事務(wù),盡管有一些操作已經(jīng)被回滾。典型地,它對(duì)應(yīng)于JDBC的保存點(diǎn),所以只對(duì)JDBC事務(wù)資源起作用。
SUPPORTS
支持當(dāng)前事務(wù)。如果當(dāng)前有事務(wù),就參與進(jìn)來,如果沒有,就以非事務(wù)的方式運(yùn)行。這樣的一個(gè)邏輯事務(wù)范圍,它背后可能沒有實(shí)際的物理事務(wù),此時(shí)的事務(wù)也成為空事務(wù)。
NOT_SUPPORTED
不支持當(dāng)前事務(wù)。總是以非事務(wù)方式運(yùn)行。當(dāng)前的事務(wù)會(huì)被掛起,并在適合的時(shí)候恢復(fù)。
MANDATORY
支持當(dāng)前事務(wù)。如果當(dāng)前沒有事務(wù)存在,就拋出異常。
NEVER
不支持當(dāng)前事務(wù)。如果當(dāng)前有事務(wù)存在,就拋出異常。
事務(wù)的隔離級(jí)別
DEFAULT,READ_UNCOMMITTED,READ_COMMITTED,REPEATABLE_READ,SERIALIZABLE
臟讀
一個(gè)事務(wù)修改了一行數(shù)據(jù)但沒有提交,第二個(gè)事務(wù)可以讀取到這行被修改的數(shù)據(jù),如果第一個(gè)事務(wù)回滾,第二個(gè)事務(wù)獲取到的數(shù)據(jù)將是無效的。
不可重復(fù)讀
一個(gè)事務(wù)讀取了一行數(shù)據(jù),第二個(gè)事務(wù)修改了這行數(shù)據(jù),第一個(gè)事務(wù)重新讀取這行數(shù)據(jù),將獲得到不同的值。
幻讀
一個(gè)事務(wù)按照一個(gè)where條件讀取所有符合的數(shù)據(jù)行,第二個(gè)事務(wù)插入了一行數(shù)據(jù)且恰好也滿足這個(gè)where條件,第一個(gè)事務(wù)再以這個(gè)where條件重新讀取,將會(huì)獲取額外多出來的這一行。
幫助記憶:
寫讀是臟讀,讀寫讀是不可重復(fù)讀,where insert where是幻讀。
DEFAULT
使用底層數(shù)據(jù)存儲(chǔ)的默認(rèn)隔離級(jí)別。MySQL的默認(rèn)隔離級(jí)別是REPEATABLE-READ。
READ_UNCOMMITTED
讀未提交。臟讀、不可重復(fù)讀、幻讀都會(huì)發(fā)生。
READ_COMMITTED
讀已提交。臟讀不會(huì)發(fā)生,不可重復(fù)讀、幻讀都會(huì)發(fā)生。
REPEATABLE_READ
可重復(fù)讀。臟讀、不可重復(fù)讀都不會(huì)發(fā)生,幻讀會(huì)發(fā)生。
SERIALIZABLE
可串行化。臟讀、不可重復(fù)讀、幻讀都不會(huì)發(fā)生。
spring事務(wù)考點(diǎn)我就總結(jié)在這里了,如果有遺漏或者改進(jìn)還請各位大佬留言指點(diǎn)
同時(shí)spring事務(wù)這個(gè)知識(shí)點(diǎn)也為大家總結(jié)我的部分學(xué)習(xí)筆記和與之相匹配的架構(gòu)進(jìn)階視頻資料:
spring事務(wù)部分筆記
資料獲取方式:請加JAVA架構(gòu)技術(shù)交流群:714827309
點(diǎn)擊鏈接加入群聊【JAVA高級(jí)架構(gòu)技術(shù)交流】:https://jq.qq.com/?_wv=1027&k...
注:加群要求
1、具有1-5工作經(jīng)驗(yàn)的,面對(duì)目前流行的技術(shù)不知從何下手,需要突破技術(shù)瓶頸的可以加。
2、在公司待久了,過得很安逸,但跳槽時(shí)面試碰壁。需要在短時(shí)間內(nèi)進(jìn)修、跳槽拿高薪的可以加。
3、如果沒有工作經(jīng)驗(yàn),但基礎(chǔ)非常扎實(shí),對(duì)java工作機(jī)制,常用設(shè)計(jì)思想,常用java開發(fā)框架掌握熟練的,可以加。
4、覺得自己很牛B,一般需求都能搞定。但是所學(xué)的知識(shí)點(diǎn)沒有系統(tǒng)化,很難在技術(shù)領(lǐng)域繼續(xù)突破的可以加。
5.阿里Java高級(jí)大牛直播講解知識(shí)點(diǎn),分享知識(shí),多年工作經(jīng)驗(yàn)的梳理和總結(jié),帶著大家全面、科學(xué)地建立自己的技術(shù)體系和技術(shù)認(rèn)知!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/73770.html
摘要:做一個(gè)靠譜且有責(zé)任心的人很多公司在內(nèi)部的面試細(xì)則上面都會(huì)注明這一點(diǎn),如果價(jià)值觀或是人品問題會(huì)直接否決。沒有一個(gè)面試官不想找一個(gè)技術(shù)出眾又有責(zé)任心的人,請相信我,責(zé)任心非常重要,更有利于今后的晉升。 關(guān)注微信公眾號(hào):進(jìn)擊的java程序員K 每日精選BAT技術(shù)文章,面試真題,源碼資料。 今天分享的BAT等一線互聯(lián)網(wǎng)公司面試經(jīng)驗(yàn): 面試前的心態(tài)準(zhǔn)備(3點(diǎn)建議)技術(shù)硬實(shí)力包含的范圍(50題目...
摘要:做一個(gè)靠譜且有責(zé)任心的人很多公司在內(nèi)部的面試細(xì)則上面都會(huì)注明這一點(diǎn),如果價(jià)值觀或是人品問題會(huì)直接否決。沒有一個(gè)面試官不想找一個(gè)技術(shù)出眾又有責(zé)任心的人,請相信我,責(zé)任心非常重要,更有利于今后的晉升。 關(guān)注微信公眾號(hào):進(jìn)擊的java程序員K 每日精選BAT技術(shù)文章,面試真題,源碼資料。 今天分享的BAT等一線互聯(lián)網(wǎng)公司面試經(jīng)驗(yàn): 面試前的心態(tài)準(zhǔn)備(3點(diǎn)建議)技術(shù)硬實(shí)力包含的范圍(50題目...
閱讀 3835·2021-11-24 09:39
閱讀 3752·2021-11-22 12:07
閱讀 1105·2021-11-04 16:10
閱讀 798·2021-09-07 09:59
閱讀 1902·2019-08-30 15:55
閱讀 935·2019-08-30 15:54
閱讀 724·2019-08-29 14:06
閱讀 2473·2019-08-27 10:54