Spring的事務(wù)傳播性與隔離級別

一锨并、事務(wù)的四個特性

l?原子性:一個事務(wù)中所有對數(shù)據(jù)庫的操作是一個不可分割的操作序列狰闪,要么全做辛润,要么全部做永淌。

l?一致性:數(shù)據(jù)不會因為事務(wù)的執(zhí)行而遭到破壞崎场。

l?隔離性:一個事務(wù)的執(zhí)行,不受其他事務(wù)(進程)的干擾遂蛀。既并發(fā)執(zhí)行的個事務(wù)之間互不干擾谭跨。

l?持久性:一個事務(wù)一旦提交,它對數(shù)據(jù)庫的改變將是永久的。


二螃宙、事務(wù)的實現(xiàn)方式

????? 實現(xiàn)方式共有兩種:編碼方式蛮瞄;聲明式事務(wù)管理方式。

?基于AOP技術(shù)實現(xiàn)的聲明式事務(wù)管理谆扎,實質(zhì)就是:在方法執(zhí)行前后進行攔截挂捅,然后在目標方法開始之前創(chuàng)建并加入事務(wù),執(zhí)行完目標方法后根據(jù)執(zhí)行情況提交或回滾事務(wù)堂湖。

聲明式事務(wù)管理又有兩種方式:一種是基于XML配置文件的方式闲先;另一種是在業(yè)務(wù)方法上添加@Transactional注解,將事務(wù)規(guī)則應(yīng)用到業(yè)務(wù)邏輯中(一般定義在service層)无蜂。

三伺糠、創(chuàng)建事務(wù)的時機

????? 是否需要創(chuàng)建事務(wù),是由事務(wù)傳播行為控制的斥季。讀數(shù)據(jù)不需要或只為其指定只讀事務(wù)训桶,而數(shù)據(jù)的插入、修改酣倾、刪除就需要進行事務(wù)管理了舵揭,這是由事務(wù)的隔離級別控制的。

????? 事務(wù)具有7個傳播級別和4個隔離級別灶挟,傳播級別定義的是事務(wù)創(chuàng)建的時機琉朽,隔離級別定義的是對并發(fā)事務(wù)數(shù)據(jù)讀取的控制。

四稚铣、事務(wù)的傳播級別

????? 以下是事務(wù)的7種傳播級別:

l?PROPAGATION_REQUIRED

默認的Spring事務(wù)傳播級別箱叁,使用該級別的特點是:如果上下文中已經(jīng)存在事務(wù),那么就加入到事務(wù)中執(zhí)行惕医;如果當前上下文中不存在事務(wù)耕漱,則新建事務(wù)執(zhí)行。所以這個級別通常能滿足處理大多數(shù)的業(yè)務(wù)場景抬伺。

l?PROPAGATION_SUPPORTS

從字面意思就知道螟够,supports,支持峡钓,該傳播級別的特點是:如果上下文存在事務(wù)妓笙,則支持事務(wù)加入事務(wù),如果沒有事務(wù)能岩,則使用非事務(wù)的方式執(zhí)行寞宫。所以說,并非所有的包含在TransactionTemplate.execute方法中的代碼都會有事務(wù)支持拉鹃。這個通常是用來處理那些并非原子性的非核心業(yè)務(wù)邏輯操作辈赋。應(yīng)用場景較少鲫忍。

l?PROPAGATION_MANDATORY

該級別的事務(wù)要求上下文中必須要存在事務(wù),否則就會拋出異常钥屈!配置該方式的傳播級別是有效的控制上下文調(diào)用代碼遺漏添加事務(wù)控制的保證手段悟民。比如一段代碼不能單獨被調(diào)用執(zhí)行,但是一旦被調(diào)用篷就,就必須有事務(wù)包含的情況射亏,就可以使用這個傳播級別。

l?PROPAGATION_REQUIRES_NEW

從字面即可知道腻脏,new鸦泳,每次都要一個新事務(wù),該傳播級別的特點是:每次都會新建一個事務(wù)永品,并且同時將上下文中的事務(wù)掛起,執(zhí)行當前新建事務(wù)完成以后击纬,上下文事務(wù)恢復(fù)再執(zhí)行鼎姐。

這是一個很有用的傳播級別,舉一個應(yīng)用場景:現(xiàn)在有一個發(fā)送100個紅包的操作更振,在發(fā)送之前炕桨,要做一些系統(tǒng)的初始化、驗證肯腕、數(shù)據(jù)記錄操作献宫,然后發(fā)送100封紅包,然后再記錄發(fā)送日志实撒,發(fā)送日志要求100%的準確姊途,如果日志不準確,那么整個父事務(wù)邏輯需要回滾知态。

怎么處理整個業(yè)務(wù)需求呢捷兰?就是通過這個PROPAGATION_REQUIRES_NEW級別的事務(wù)傳播控制就可以完成。發(fā)送紅包的子事務(wù)不會直接影響到父事務(wù)的提交和回滾负敏。

l?PROPAGATION_NOT_SUPPORTED

這個也可以從字面得知贡茅,not supported,不支持其做,當前級別的特點是:若上下文中存在事務(wù)顶考,則掛起事務(wù),執(zhí)行當前邏輯妖泄,結(jié)束后恢復(fù)上下文的事務(wù)。

這個級別有什么好處浮庐?可以幫助你將事務(wù)盡可能的縮小甚负。我們知道一個事務(wù)越大柬焕,它存在的風(fēng)險也就越多。所以在處理事務(wù)的過程中梭域,要保證盡可能的縮小范圍斑举。比如一段代碼,是每次邏輯操作都必須調(diào)用的病涨,比如循環(huán)1000次的某個非核心業(yè)務(wù)邏輯操作富玷。這樣的代碼如果包在事務(wù)中,勢必造成事務(wù)太大既穆,導(dǎo)致出現(xiàn)一些難以考慮周全的異常情況赎懦,所以事務(wù)的這個傳播級別就派上用場了。用當前級別的事務(wù)模板包含起來就可以了幻工。

l?PROPAGATION_NEVER

該事務(wù)更嚴格励两,上面一個事務(wù)傳播級別只是不支持而已,有事務(wù)就掛起囊颅,而PROPAGATION_NEVER傳播級別要求上下文中不能存在事務(wù)当悔,一旦有事務(wù),就拋出runtime異常踢代,強制停止執(zhí)行盲憎!這個級別上輩子跟事務(wù)有仇。

l?PROPAGATION_NESTED

從字面也可知道胳挎,nested饼疙,嵌套級別事務(wù)。該傳播級別的特征是:如果上下文中存在事務(wù)慕爬,則嵌套事務(wù)執(zhí)行窑眯,如果不存在事務(wù),則新建事務(wù)澡罚。

那么什么是嵌套事務(wù)呢伸但?很多人都不理解,我看過一些博客留搔,都是有些理解偏差更胖。

嵌套是子事務(wù)嵌套在父事務(wù)中執(zhí)行,子事務(wù)是父事務(wù)的一部分隔显,在進入子事務(wù)之前却妨,父事務(wù)建立一個回滾點,叫save point括眠,然后執(zhí)行子事務(wù)彪标,這個子事務(wù)的執(zhí)行也算是父事務(wù)的一部分,然后子事務(wù)執(zhí)行結(jié)束掷豺,父事務(wù)繼續(xù)執(zhí)行捞烟。重點就在于那個save point薄声。看幾個問題就明了了:

(1)?? 如果子事務(wù)回滾题画,會發(fā)生什么默辨?

父事務(wù)會回滾到進入子事務(wù)前建立的save point,然后嘗試其他的事務(wù)或者其他的業(yè)務(wù)邏輯苍息,父事務(wù)之前的操作不會受到影響缩幸,更不會自動回滾。

(2)?? 如果父事務(wù)回滾竞思,會發(fā)生什么表谊?

父事務(wù)回滾,子事務(wù)也會跟著回滾盖喷!為什么呢爆办,因為父事務(wù)結(jié)束之前,子事務(wù)是不會提交的课梳,我們說子事務(wù)是父事務(wù)的一部分押逼,正是這個道理。

(3)?? 事務(wù)的提交惦界,是什么情況?

是父事務(wù)先提交咙冗,然后子事務(wù)提交沾歪,還是子事務(wù)先提交,父事務(wù)再提交雾消?答案是第二種情況灾搏,還是那句話,子事務(wù)是父事務(wù)的一部分立润,由父事務(wù)統(tǒng)一提交狂窑。

現(xiàn)在你再體會一下這個”嵌套“,是不是有那么點意思了桑腮?

以上是事務(wù)的7個傳播級別泉哈,在日常應(yīng)用中,通称铺郑可以滿足各種業(yè)務(wù)需求丛晦,但是除了傳播級別,在讀取數(shù)據(jù)庫的過程中提陶,如果兩個事務(wù)并發(fā)執(zhí)行烫沙,那么彼此之間的數(shù)據(jù)是如何影響的呢?這就需要了解一下事務(wù)的另一個特性:數(shù)據(jù)隔離級別隙笆。

五锌蓄、事務(wù)的隔離級別

????? 數(shù)據(jù)隔離級別分為不同的4種:

l?SERIALIZABLE

最嚴格的級別升筏,事務(wù)串行執(zhí)行,資源消耗最大瘸爽。

l?REPEATABLE_READ

保證了一個事務(wù)不會修改已經(jīng)由另一個事務(wù)讀取但未提交(回滾)的數(shù)據(jù)您访。避免了“臟讀取”和“不可重復(fù)讀取”的情況,但是帶來了更多的性能損失蝶糯。

l?READ_COMMITTED

大多數(shù)主流數(shù)據(jù)庫的默認事務(wù)等級洋只,保證了一個事務(wù)不會讀到另一個并行事務(wù)已修改但未提交的數(shù)據(jù),避免了“臟讀取”昼捍。該級別適用于大多數(shù)系統(tǒng)识虚。

l?READ_UNCOMMITTED

保證了讀取過程中不會讀取到非法數(shù)據(jù)。


????? 上面的解釋其實每個定義都有一些拗口妒茬,其中涉及到幾個術(shù)語:臟讀担锤、不可重復(fù)讀、幻讀乍钻。這里解釋一下:

l?臟讀(Dirty Reads)

所謂的臟讀肛循,其實就是讀到了別的事務(wù)回滾前的臟數(shù)據(jù)。比如事務(wù)B執(zhí)行過程中修改了數(shù)據(jù)X银择,在未提交前多糠,事務(wù)A讀取了X,而事務(wù)B卻回滾了浩考,這樣事務(wù)A就形成了臟讀夹孔。

l?不可重復(fù)讀(Non-RepeatableReads)

不可重復(fù)讀字面含義已經(jīng)很明了了,比如事務(wù)A首先讀取了一條數(shù)據(jù)析孽,然后執(zhí)行邏輯的時候搭伤,事務(wù)B將這條數(shù)據(jù)改變了,然后事務(wù)A再次讀取的時候袜瞬,發(fā)現(xiàn)數(shù)據(jù)不匹配了怜俐,就是所謂的不可重復(fù)讀了。

l?幻讀

小的時候數(shù)手指邓尤,第一次數(shù)十10個拍鲤,第二次數(shù)是11個,怎么回事裁赠?產(chǎn)生幻覺了殿漠?

幻讀也是這樣子,事務(wù)A首先根據(jù)條件索引得到10條數(shù)據(jù)佩捞,然后事務(wù)B改變了數(shù)據(jù)庫一條數(shù)據(jù)绞幌,導(dǎo)致也符合事務(wù)A當時的搜索條件,這樣事務(wù)A再次搜索發(fā)現(xiàn)有11條數(shù)據(jù)了一忱,就產(chǎn)生了幻讀莲蜘。

事務(wù)隔離級別對照關(guān)系表:


? 所以最安全的谭确,是Serializable,但是伴隨而來也是高昂的性能開銷票渠。

另外逐哈,事務(wù)常用的兩個屬性:①?readonly,設(shè)置事務(wù)為只讀以提升性能问顷;②?timeout昂秃,設(shè)置事務(wù)的超時時間,一般用于防止大事務(wù)的發(fā)生杜窄。

六肠骆、Spring管理聲明式事務(wù)的配置

1. 基于XML配置文件的AOP和TX配置方式

????? applicationContext.xml配置文件:

applicationContext.xml配置文件:

七、簡述Hibernate的SessionFactory和Session

l? SessionFactory對象

Hibernate中SessionFactory對象的創(chuàng)建代價很高塞耕,它是線程安全的對象蚀腿,被設(shè)計成可以為所有的應(yīng)用程序線程所共享。通常扫外,SessionFactory會在應(yīng)用程序啟動時創(chuàng)建莉钙,一旦創(chuàng)建了SessionFactory將不會輕易關(guān)閉,只有當應(yīng)用關(guān)閉時筛谚,SessionFactory才會關(guān)閉磁玉。

l? Session對象

Hibernate中Session對象是輕量級的,它是線程不安全的驾讲。對于單個業(yè)務(wù)進程蜀涨、單個工作單元而言,Session只被使用一次蝎毡。創(chuàng)建Session時,并不會立即打開與數(shù)據(jù)庫之間的連接氧枣,Session只在需要進行數(shù)據(jù)庫操作時沐兵,才會獲取JDBC連接。因此便监,打開和關(guān)閉Session扎谎,并不會對性能造成很大的影響。甚至即使無法確定一個請求是否需要數(shù)據(jù)訪問烧董,也可以打開Session對象毁靶,因為如果不進行數(shù)據(jù)庫訪問,Session不會獲取JDBC連接逊移。

使用Spring管理Hibernate的事務(wù)预吆,在每個DAO操作中使用SessionFactory.getCurrentSession()方法,該方法可以得到當前事務(wù)綁定的Session胳泉。同時當前的Session和關(guān)聯(lián)的Hibernate事務(wù)被綁定到當前線程上拐叉,雖然Session不是線程安全的岩遗,但是通過這樣的方式,每一個Session都處于單線程中凤瘦,避免Session線程安全問題宿礁。

l? 不通過Spring管理事務(wù),開啟事務(wù)的主動性

在SessionFactory.openSession()中蔬芥,Hibernate會初始化數(shù)據(jù)庫連接梆靖,與此同時,將其 AutoCommit設(shè)為關(guān)閉狀態(tài)笔诵,這就是說返吻,從SessionFactory獲得Session,其自動提交屬性就已經(jīng)被關(guān)閉了嗤放,事務(wù)需要主動思喊、顯示的調(diào)用才能生效,下面的代碼不會對事務(wù)性數(shù)據(jù)庫產(chǎn)生任何效果:

?session?= sessionFactory.openSession();

?session.save(user);

?session.close();

? 如果要使得代碼真正作用到數(shù)據(jù)庫次酌,必須顯示的調(diào)用Transaction指令:

?session?= sessionFactory.openSession();

Transaction?tx?=?session.beginTransaction();

?session.save(user);

?tx.commit();

?session.close();

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末恨课,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子岳服,更是在濱河造成了極大的恐慌剂公,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吊宋,死亡現(xiàn)場離奇詭異纲辽,居然都是意外死亡,警方通過查閱死者的電腦和手機璃搜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進店門拖吼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人这吻,你說我怎么就攤上這事吊档。” “怎么了唾糯?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵怠硼,是天一觀的道長。 經(jīng)常有香客問我移怯,道長香璃,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任舟误,我火速辦了婚禮葡秒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己同云,他們只是感情好糖权,可當我...
    茶點故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著炸站,像睡著了一般星澳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上旱易,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天禁偎,我揣著相機與錄音,去河邊找鬼阀坏。 笑死如暖,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的忌堂。 我是一名探鬼主播盒至,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼士修!你這毒婦竟也來了枷遂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤棋嘲,失蹤者是張志新(化名)和其女友劉穎酒唉,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沸移,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡痪伦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了雹锣。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片网沾。...
    茶點故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蕊爵,靈堂內(nèi)的尸體忽然破棺而出绅这,到底是詐尸還是另有隱情,我是刑警寧澤在辆,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站度苔,受9級特大地震影響匆篓,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜寇窑,卻給世界環(huán)境...
    茶點故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一鸦概、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦窗市、人聲如沸先慷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽论熙。三九已至,卻和暖如春摄狱,著一層夾襖步出監(jiān)牢的瞬間脓诡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工媒役, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留祝谚,地道東北人。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓酣衷,卻偏偏與公主長得像交惯,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子穿仪,可洞房花燭夜當晚...
    茶點故事閱讀 44,947評論 2 355

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