事務(wù)是訪(fǎng)問(wèn)并更新數(shù)據(jù)庫(kù)中各種數(shù)據(jù)的最小單元,在事務(wù)的操作中饼记,要么都修改成功新荤,要么都修改失敗凡橱。它的主要目的是:將數(shù)據(jù)庫(kù)從一個(gè)一直狀態(tài)轉(zhuǎn)換成另一種一直狀態(tài)小作。
事務(wù)的四個(gè)特性是:
- 原子性(atomicity):原子性指整個(gè)數(shù)據(jù)庫(kù)事務(wù)是不可分割的工作單位。只有使事務(wù)中所有的數(shù)據(jù)庫(kù)操作都執(zhí)行成功稼钩,才算整個(gè)事務(wù)成功顾稀。
- 一致性(consistency):一致性指事務(wù)將數(shù)據(jù)庫(kù)從一種狀態(tài)轉(zhuǎn)變?yōu)橄乱环N一致的狀態(tài)。
- 隔離性(isolation):隔離性還有其他的稱(chēng)呼坝撑,如并發(fā)控制(concurrency control)静秆、可串行化(serializability)、鎖(locking)等绍载。事務(wù)的隔離性要求每個(gè)讀寫(xiě)事務(wù)的對(duì)象對(duì)其他事務(wù)的操作對(duì)象能相互分離诡宗,即該事務(wù)提交前對(duì)其他事務(wù)都不可見(jiàn)滔蝉,通常這使用鎖來(lái)實(shí)現(xiàn)击儡。
- 持久性(durability):事務(wù)一旦提交,其結(jié)果就是永久性的蝠引。
事務(wù)隔離性由鎖來(lái)實(shí)現(xiàn)阳谍,原子性、一致性和持久性是通過(guò)數(shù)據(jù)庫(kù)的redo log和undolog來(lái)實(shí)現(xiàn)的螃概。
事務(wù)的隔離級(jí)別:
-
READ UNCOMMITTED
:未提交讀矫夯,會(huì)產(chǎn)生臟讀。 -
READ COMMITTED
:讀已提交(不可重復(fù)讀)熊尉,會(huì)產(chǎn)生幻讀焚挠,oracl的默認(rèn)隔離級(jí)別尺栖。 -
REPEATABLE READ
:可重復(fù)讀,不會(huì)產(chǎn)生換行和臟讀递沪,通過(guò)MVCC來(lái)實(shí)現(xiàn),MySQL的默認(rèn)隔離級(jí)別综液。 -
SERIALIZABLE
:串行化款慨。
事務(wù)的分類(lèi)
從事務(wù)理論的角度來(lái)說(shuō),可以把事務(wù)分為以下幾種類(lèi)型:
- 扁平事務(wù)(Flat Transactions)
- 帶有保存點(diǎn)的扁平事務(wù)(Flat Transactions with Savepoints)
- 鏈?zhǔn)聞?wù)(Chained Transactions)
- 嵌套事務(wù)(Nested Transactions)
- 分布式事務(wù)(Distributed Transactions)
扁平事務(wù)(Flat Transactions)
扁平事務(wù)事務(wù)時(shí)最簡(jiǎn)單的一種事務(wù)谬莹,也是平時(shí)用得最多的一種檩奠,在扁平事務(wù)中桩了,所有操作都處于同一層次,其由BEGIN WORK
開(kāi)始埠戳,由COMMIT WORK
或ROLLBACK WORK
結(jié)束井誉,其間的操作是原子的,要么都執(zhí)行整胃,要么都回滾送悔。
帶有保存點(diǎn)的扁平事務(wù)(Flat Transactions with Savepoints)
除了支持扁平事務(wù)支持的操作外,允許在事務(wù)執(zhí)行過(guò)程中回滾到同一事務(wù)中較早的一個(gè)狀態(tài)爪模。這是因?yàn)槟承┦聞?wù)可能在執(zhí)行過(guò)程中出現(xiàn)的錯(cuò)誤并不會(huì)導(dǎo)致所有的操作都無(wú)效欠啤,放棄整個(gè)事務(wù)不合乎要求,開(kāi)銷(xiāo)也太大屋灌。
保存點(diǎn)(Savepoint)用來(lái)通知系統(tǒng)應(yīng)該記住事務(wù)當(dāng)前的狀態(tài)洁段,以便當(dāng)之后發(fā)生錯(cuò)誤時(shí),事務(wù)能回到保存點(diǎn)當(dāng)時(shí)的狀態(tài)共郭。其實(shí)扁平事務(wù)就是只有一個(gè)保存點(diǎn)的事務(wù)祠丝。
當(dāng)發(fā)生回滾是只有執(zhí)行一次ROLLBACK WORK:7
命名表示回滾到保存點(diǎn)7的位置,如果還需要回滾需要繼續(xù)執(zhí)行ROLLBACK WORK:x
命令(x表示保存點(diǎn)編號(hào))除嘹,帶有保存點(diǎn)的扁平事務(wù)能回滾到任意正確的保存點(diǎn)写半。
帶保存點(diǎn)事務(wù)的保存點(diǎn)是非持久化的,所以當(dāng)系統(tǒng)崩潰時(shí)保存點(diǎn)就會(huì)丟失尉咕,這時(shí)系統(tǒng)恢復(fù)時(shí)叠蝇,事務(wù)需要從頭開(kāi)始,從新執(zhí)行年缎。為了解決這個(gè)問(wèn)題提出了鏈?zhǔn)聞?wù)悔捶。
鏈?zhǔn)聞?wù)(Chained Transactions)
鏈?zhǔn)聞?wù)是在提交一個(gè)事務(wù)時(shí),釋放不需要的數(shù)據(jù)對(duì)象单芜,將必要的處理上下文隱式地傳給下一個(gè)要開(kāi)始的事務(wù)蜕该。
鏈?zhǔn)聞?wù)有個(gè)缺點(diǎn)就是當(dāng)需要回滾事務(wù)的時(shí)候,只能恢復(fù)到最近的一個(gè)保存點(diǎn)洲鸠。
嵌套事務(wù)(Nested Transactions)
嵌套事務(wù)是一個(gè)層次結(jié)構(gòu)框架堂淡。由一個(gè)頂層事務(wù)(top-leveltransaction)控制著各個(gè)層次的事務(wù)。頂層事務(wù)之下嵌套的事務(wù)被稱(chēng)為子事務(wù)(subtransaction)扒腕,其控制每一個(gè)局部的變換。
嵌套事務(wù)特性:
- 子事務(wù)可以是嵌套事務(wù),也可以是扁平事務(wù)内狗。
- 最后葉子節(jié)點(diǎn)的事務(wù)一定是扁平事務(wù)。
- 子事務(wù)的提交并不會(huì)立即生效赂鲤,只有等到頂層事務(wù)提交后子事務(wù)才會(huì)真正提交。
- 任意一個(gè)子事務(wù)的回滾都會(huì)導(dǎo)致所有子事務(wù)的回滾。
分布式事務(wù)(Distributed Transactions)
在分布式環(huán)境下運(yùn)行的扁平事務(wù)仑鸥,因此需要根據(jù)數(shù)據(jù)所在位置訪(fǎng)問(wèn)網(wǎng)絡(luò)中的不同節(jié)點(diǎn)。分布式事務(wù)的常用解決方案有2pc(兩段式提交)、3pc(三段式提交)获列、TCC(Try迫悠、Confirm艺玲、Cancel)和基于消息的最終一致性搁拙。
分布式事務(wù)的大致實(shí)現(xiàn)思想都是引入一個(gè)事務(wù)管理器(協(xié)調(diào)者)來(lái)管理參與者服務(wù)的事務(wù)酪碘,由事務(wù)管理器來(lái)統(tǒng)一調(diào)度參與服務(wù)的事務(wù)到底是提交還是回滾徙赢。
InnoDB實(shí)現(xiàn)了XA協(xié)議,使用了2pc(兩段式提交)的方式來(lái)實(shí)現(xiàn)了分布式事務(wù)。
InnoDB存儲(chǔ)引擎支持扁平事務(wù)、帶有保存點(diǎn)的事務(wù)、鏈?zhǔn)聞?wù)、分布式事務(wù)。不支持嵌套事務(wù)。
2pc(兩段式提交)
原理
第一階段是表決階段哎媚,由事務(wù)管理者(協(xié)調(diào)者)來(lái)發(fā)發(fā)起事務(wù),并詢(xún)問(wèn)所有參與者是否可以提交事務(wù)捻悯。
第二階段是執(zhí)行階段,協(xié)調(diào)者收到所有參與者的反饋,根據(jù)反饋的結(jié)果決定所有參與者是commit
還是rollback
兽泣。
優(yōu)點(diǎn)
- 原理簡(jiǎn)單
- 實(shí)現(xiàn)方便
缺點(diǎn)
- 同步柱塞稠鼻,當(dāng)參與1先完成第一階段的時(shí)候,需要阻塞等待參與者2的處理候齿。
- 單點(diǎn)故障熙暴,協(xié)調(diào)者存在單點(diǎn)故障,一點(diǎn)掛掉可能導(dǎo)致參與者一直阻塞慌盯。
- 數(shù)據(jù)不一致周霉,當(dāng)參與者1收到了commit消息,但是參與者2并沒(méi)收到的時(shí)候就會(huì)存在數(shù)據(jù)不一致的情況亚皂。
- 容錯(cuò)機(jī)制不完善俱箱,還是協(xié)調(diào)者掛了后會(huì)導(dǎo)致所有參與者同步阻塞。
3pc(三段式提交)
三階段提交孕讳,也叫三階段提交協(xié)議匠楚,是二階段提交(2PC)的改進(jìn)版本,主要是在協(xié)調(diào)者和參與者之間都引入了超時(shí)機(jī)制厂财;在第一階段和第二階段中插入一個(gè)準(zhǔn)備階段。保證了在最后提交階段之前各參與節(jié)點(diǎn)的狀態(tài)是一致的峡懈。
原理
第一階段璃饱,由事務(wù)管理者(協(xié)調(diào)者)來(lái)發(fā)發(fā)起事務(wù),并詢(xún)問(wèn)所有參與者是否可以提交事務(wù)肪康,這一步非臣远瘢快速撩穿,不會(huì)操作數(shù)據(jù)庫(kù)。
第二階段谒撼,協(xié)調(diào)者詢(xún)問(wèn)是否可以提交事務(wù)食寡,并詢(xún)問(wèn)所有參與者是否可以提交事務(wù),這一步才會(huì)真正操作數(shù)據(jù)庫(kù)廓潜。
第三階段抵皱,協(xié)調(diào)者收到所有參與者的反饋,根據(jù)反饋的結(jié)果決定所有參與者是commit
還是rollback
辩蛋,如果超時(shí)還是沒(méi)有收到反饋這時(shí)也提交事務(wù)呻畸。
優(yōu)點(diǎn)
- 改善同步阻塞的范圍,如果超時(shí)會(huì)中斷事務(wù)悼院。
- 改善單點(diǎn)故障伤为,最后一步如果協(xié)調(diào)者掛掉,參與者也會(huì)提交事務(wù)据途。
缺點(diǎn)
- 同步柱塞绞愚,還是存在同步阻塞的問(wèn)題,只是引入了超時(shí)機(jī)制颖医,阻塞問(wèn)題得到了一定的改善爽醋。
- 單點(diǎn)故障,還是有單點(diǎn)故障便脊,只是有超時(shí)機(jī)制蚂四,這個(gè)問(wèn)題得到了一定的改善。
- 數(shù)據(jù)不一致哪痰,當(dāng)參與者1收到了commit消息遂赠,但是參與者2并沒(méi)收到的時(shí)候就會(huì)存在數(shù)據(jù)不一致的情況。
- 容錯(cuò)機(jī)制不完善晌杰,與2pc相比有一定的改善跷睦。
TCC(Try、Confirm肋演、Cancel)
TCC 其實(shí)就是采用的補(bǔ)償機(jī)制抑诸,其核心思想是:針對(duì)每個(gè)操作,都要注冊(cè)一個(gè)與其對(duì)應(yīng)的確認(rèn)和補(bǔ)償(撤銷(xiāo))操作爹殊,TCC本質(zhì)上也是一個(gè)兩階段提交蜕乡。它分為三個(gè)階段:
Try 階段主要是對(duì)業(yè)務(wù)系統(tǒng)做檢測(cè)(一致性)及資源預(yù)留(準(zhǔn)隔離性)。
Confirm 階段主要是對(duì)業(yè)務(wù)系統(tǒng)做確認(rèn)提交梗夸,Try階段執(zhí)行成功并開(kāi)始執(zhí)行 Confirm階段時(shí)层玲,默認(rèn) Confirm階段是不會(huì)出錯(cuò)的,即:只要Try成功,Confirm一定成功辛块。Confirm操作需要滿(mǎn)足冪等性畔派。
Cancel 階段主要是釋放Try階段預(yù)留的業(yè)務(wù)資源,該階段也需要保證冪等润绵。
優(yōu)點(diǎn)
跟2PC比起來(lái)线椰,實(shí)現(xiàn)以及流程相對(duì)簡(jiǎn)單了一些,但數(shù)據(jù)的一致性比2PC也要差一些
缺點(diǎn)
缺點(diǎn)還是比較明顯的尘盼,在2,3步中都有可能失敗憨愉。TCC屬于應(yīng)用層的一種補(bǔ)償方式,所以需要程序員在實(shí)現(xiàn)的時(shí)候多寫(xiě)很多補(bǔ)償?shù)拇a悔叽,在一些場(chǎng)景中莱衩,一些業(yè)務(wù)流程可能用TCC不太好定義及處理。
分布式事務(wù)框架Seata
https://github.com/seata/seata
https://mp.weixin.qq.com/s/Xh2jfZgD7Qallh_DAUbeVg
不好的事務(wù)習(xí)慣
- 在循環(huán)中提交事務(wù)娇澎,循環(huán)中提交事務(wù)有兩個(gè)問(wèn)題:1笨蚁、性能問(wèn)題;2趟庄、當(dāng)程序出現(xiàn)異常括细,數(shù)據(jù)不能全部回滾。
- 使用自動(dòng)提交和回滾戚啥,在編寫(xiě)應(yīng)用程序開(kāi)發(fā)時(shí)奋单,最好把事務(wù)的控制權(quán)限交給開(kāi)發(fā)人員,即在程序端進(jìn)行事務(wù)的開(kāi)始和結(jié)束猫十。
- 使用長(zhǎng)事務(wù)览濒,使用長(zhǎng)事務(wù)當(dāng)系統(tǒng)發(fā)生故障時(shí),重新開(kāi)始一個(gè)事務(wù)的代價(jià)比較大拖云;長(zhǎng)事務(wù)還會(huì)長(zhǎng)期占用MySQL資源贷笛,導(dǎo)致其他操作無(wú)法及時(shí)的去執(zhí)行。