Spring事務(wù)的傳播機制
我們都知道,在數(shù)據(jù)庫中有這事務(wù)的存在,但是更多的時候,我們還會被經(jīng)常問到這個關(guān)于 Spring 中 事務(wù)的各種行為,又或者說是傳播機制,或者隔離級別等內(nèi)容,那么面試的時候我們應(yīng)該怎么去回答這個 Spring 事務(wù)的傳播機制以及隔離級別呢?
什么是 Spring 的事務(wù)
事務(wù)是邏輯處理原?性的保證?段,通過使?事務(wù)控制,可以極?的避免出現(xiàn)邏輯處理失敗導(dǎo)致的臟數(shù) 據(jù)等問題。
事務(wù)最重要的兩個特性,是事務(wù)的傳播級別和數(shù)據(jù)隔離級別。傳播級別定義的是事務(wù)的控制范圍,事務(wù) 隔離級別定義的是事務(wù)在數(shù)據(jù)庫讀寫??的控制范圍。
Spring事務(wù)傳播機制
PROPAGATION_REQUIRED
Spring默認(rèn)的事務(wù)傳播級別,使?該級別的特點是,如果上下?中 已經(jīng)存在事務(wù),那么就加?到事務(wù)中執(zhí)?,如果當(dāng)前上下?中不存在事務(wù),則新建事務(wù)執(zhí)?。所以這個 級別通常能滿?處理?多數(shù)的業(yè)務(wù)場景。
PROPAGATION_SUPPORTS
從字?意思就知道,supports,?持,該傳播級別的特點是,如果上下?存在事務(wù),則?持事務(wù)加?事務(wù),如果沒有事務(wù),則使??事務(wù)的?式執(zhí)?。所以說,并?所有的包在transactionTemplate.execute中的代碼都會有事務(wù)?持。這個通常是?來處理那些并?原?性的?核?業(yè)務(wù)邏輯操作。應(yīng)?場景較少。
PROPAGATION_MANDATORY
該級別的事務(wù)要求上下?中必須要存在事務(wù),否則就會拋出異常!配置該?式的傳播級別是有效的控制上下?調(diào)?代碼遺漏添加事務(wù)控制的保證?段。?如?段代碼不能單獨被調(diào)?執(zhí)?,但是?旦被調(diào)?,就必須有事務(wù)包含的情況,就可以使?這個傳播級別。
PROPAGATION_REQUIRES_NEW
從字?即可知道,new,每次都要?個新事務(wù),該傳播級別的特點是,每次都會新建?個事務(wù),并且同時將上下?中的事務(wù)掛起,執(zhí)?當(dāng)前新建事務(wù)完成以后,上下?事務(wù)恢復(fù)再執(zhí)?。
這是?個很有?的傳播級別,舉?個應(yīng)?場景:現(xiàn)在有?個發(fā)送100個紅包的操作,在發(fā)送之前,要做 ?些系統(tǒng)的初始化、驗證、數(shù)據(jù)記錄操作,然后發(fā)送100封紅包,然后再記錄發(fā)送?志,發(fā)送?志要求 100%的準(zhǔn)確,如果?志不準(zhǔn)確,那么整個?事務(wù)邏輯需要回滾。
怎么處理整個業(yè)務(wù)需求呢?就是通過這個PROPAGATION_REQUIRES_NEW 級別的事務(wù)傳播控制就可以 完成。發(fā)送紅包的?事務(wù)不會直接影響到?事務(wù)的提交和回滾。
PROPAGATION_NOT_SUPPORTED
這個也可以從字?得知,not supported ,不?持,當(dāng)前級別的特點就是上下?中存在事務(wù),則掛起事務(wù),執(zhí)?當(dāng)前邏輯,結(jié)束后恢復(fù)上下?的事務(wù)。
這個級別有什么好處?
可以幫助你將事務(wù)極可能的縮?。我們知道?個事務(wù)越?,它存在的?險也就越多。所以在處理事務(wù)的過程中,要保證盡可能的縮?范圍。?如?段代碼,是每次邏輯操作都必須調(diào)?的,?如循環(huán)1000次的某個?核?業(yè)務(wù)邏輯操作。這樣的代碼如果包在事務(wù)中,勢必造成事務(wù)太?,導(dǎo)致出現(xiàn)?些難以考慮周全的異常情況。所以這個事務(wù)這個級別的傳播級別就派上?場了。
PROPAGATION_NEVER
該事務(wù)更嚴(yán)格,上??個事務(wù)傳播級別只是不?持?已,有事務(wù)就掛 起,?PROPAGATION_NEVER傳播級別要求上下?中不能存在事務(wù),?旦有事務(wù),就拋出runtime異 常,強制停?執(zhí)?!這個級別上輩?跟事務(wù)有仇。
PROPAGATION_NESTED
字?也可知道,nested,嵌套級別事務(wù)。該傳播級別特征是,如果上 下?中存在事務(wù),則嵌套事務(wù)執(zhí)?,如果不存在事務(wù),則新建事務(wù)
Spring 事務(wù)隔離級別
Serializable
最嚴(yán)格的級別,事務(wù)串?執(zhí)?,資源消耗最?;
REPEATABLE READ
保證了?個事務(wù)不會修改已經(jīng)由另?個事務(wù)讀取但未提交(回滾)的數(shù)據(jù)。 避免了“臟讀取”和“不可重復(fù)讀取”的情況,但是帶來了更多的性能損失。
READ COMMITTED
?多數(shù)主流數(shù)據(jù)庫的默認(rèn)事務(wù)等級,保證了?個事務(wù)不會讀到另?個并?事務(wù) 已修改但未提交的數(shù)據(jù),避免了“臟讀取”。該級別適?于?多數(shù)系統(tǒng)。
Read Uncommitted
保證了讀取過程中不會讀取到?法數(shù)據(jù)
我們來舉個事務(wù)傳播的例子:
假設(shè)有一個方法childTest(),它是一個事務(wù)方法,使用了PROPAGATION_REQUIRED事務(wù)傳播選項。如果在一個事務(wù)中調(diào)用這個方法,那么它會在同一個事務(wù)中執(zhí)行。
現(xiàn)在假設(shè)有一個方法mainTest(),它調(diào)用了childTest()方法。如果在mainTest()方法中沒有顯式地聲明事務(wù),而childTest()方法中聲明了事務(wù),那么childTest()方法將在一個新的事務(wù)中執(zhí)行,這個新的事務(wù)不會影響mainTest()方法的執(zhí)行。
但是,如果mainTest()方法也使用了事務(wù)傳播選項,例如PROPAGATION_REQUIRED,那么在執(zhí)行childTest()方法時,它的事務(wù)會隱式地與mainTest()方法的事務(wù)關(guān)聯(lián)。這意味著如果childTest()方法的事務(wù)成功,則mainTest()方法的事務(wù)也會成功;如果childTest()方法的事務(wù)失敗,則mainTest()方法的事務(wù)也會失敗。
關(guān)于 Spring 的事務(wù),你了解了么?