事務(wù)和鎖
事務(wù)的定義
簡而言之: 事務(wù)(Transaction)是并發(fā)控制的基本單位。
所謂的事務(wù),它是一個(gè)操作序列,這些操作要么都執(zhí)行,要么都不執(zhí)行,它是一個(gè)不可分割的工作單位。事務(wù)的特點(diǎn) ACID
原子性(Atomicity):一個(gè)事務(wù)是一個(gè)不可分割的工作單位,事務(wù)中包括的諸操作要么都做,要么都不做。
一致性(Consistency):事務(wù)必須是使數(shù)據(jù)庫從一個(gè)一致性狀態(tài)變到另一個(gè)一致性狀態(tài)。一致性與原子性是密切相關(guān)的。
隔離性(Isolation):一個(gè)事務(wù)的執(zhí)行不能被其他事務(wù)干擾。即一個(gè)事務(wù)內(nèi)部的操作及使用的數(shù)據(jù)對并發(fā)的其他事務(wù)是隔離的,并發(fā)執(zhí)行的各個(gè)事務(wù)之間不能互相干擾。
持久性(Durability):持久性也稱永久性(permanence),指一個(gè)事務(wù)一旦提交,它對數(shù)據(jù)庫中數(shù)據(jù)的改變就應(yīng)該是永久性的。接下來的其他操作或故障不應(yīng)該對其有任何影響。
事務(wù)對應(yīng)的語句
BEGIN TRANSACTION 開始事務(wù)
COMMIT TRANSACTION 提交事務(wù)
ROLLBACK TRANSACTION 回滾事務(wù)
事務(wù)并發(fā)控制
事務(wù)不考慮隔離性引發(fā)的問題
臟讀:此種異常時(shí)因?yàn)橐粋€(gè)事務(wù)讀取了另一個(gè)事務(wù)修改了但是未提交的數(shù)據(jù),當(dāng)修改的事務(wù)進(jìn)行回滾操作時(shí)將造成讀取事務(wù)異常。
不可重復(fù)讀:在一個(gè)事務(wù)內(nèi)讀取表中的某一行數(shù)據(jù),多次讀取結(jié)果不同。(一個(gè)事務(wù)讀取到了另外一個(gè)事務(wù)提交的數(shù)據(jù))
幻讀(虛讀):指在一個(gè)事務(wù)內(nèi)讀取到了別的事務(wù)插入的數(shù)據(jù),導(dǎo)致前后讀取不一致。例如讀整個(gè)表,即表的行數(shù),例如第一次讀某個(gè)表有3條記錄,第二次讀該表又有4條記錄 (和不可重復(fù)讀的不同:不可重復(fù)讀針對的是數(shù)據(jù)的值,幻讀針對的是數(shù)據(jù)的數(shù)量)
數(shù)據(jù)庫事務(wù)隔離級別(SQL標(biāo)準(zhǔn)定義)
READ UNCOMMITTED(未提交讀):事務(wù)中的修改,即使沒有提交,其他事務(wù)也可以看得到。很容易導(dǎo)致臟讀等眾多問題,如無必要,很少使用
READ COMMITTED(提交讀):大多數(shù)數(shù)據(jù)庫系統(tǒng)默認(rèn)的隔離級別(除Mysql等)。這種隔離級別就是一個(gè)事務(wù)的開始,只能看到已經(jīng)完成的事務(wù)的結(jié)果,正在執(zhí)行的,是無法被其他事務(wù)看到的。這種級別會出現(xiàn)讀取舊數(shù)據(jù)的現(xiàn)象,即不可重復(fù)讀的問題。
REPEATABLE READ(可重復(fù)讀):解決了臟讀的問題,該級別保證了每行的記錄的結(jié)果是一致的,也就是上面說的讀了舊數(shù)據(jù)的問題,但是卻無法解決另一個(gè)問題,幻行,顧名思義就是突然蹦出來的行數(shù)據(jù)。指的就是某個(gè)事務(wù)在讀取某個(gè)范圍的數(shù)據(jù),但是另一個(gè)事務(wù)又向這個(gè)范圍的數(shù)據(jù)去插入數(shù)據(jù),導(dǎo)致多次讀取的時(shí)候,數(shù)據(jù)的行數(shù)不一致。即幻讀。–MYSQL默認(rèn)隔離級別
SERIALIZABLE(可串行化):最高的隔離級別,它通過強(qiáng)制事務(wù)串行執(zhí)行(注意是串行),避免了前面的幻讀情況,由于他大量加上鎖,導(dǎo)致大量的請求超時(shí),因此性能會比較底下,在特別需要數(shù)據(jù)一致性且并發(fā)量不需要那么大的時(shí)候才可能考慮這個(gè)隔離級別
數(shù)據(jù)庫鎖
數(shù)據(jù)庫鎖的基本類型:
X鎖:exclusive 用于寫操作
- 某數(shù)據(jù)對象在沒有加任何鎖的情況下,一個(gè)事務(wù)可以對其加X鎖,而其他事務(wù)就不能對其再加任何鎖
S鎖:share 用于讀操作
- 一個(gè)事務(wù)對某數(shù)據(jù)對象加了S 鎖后,其他事務(wù)就不能對其加X鎖,但可以加S鎖
U鎖:update
- 事務(wù)要更新數(shù)據(jù)對象時(shí),先申請?jiān)搶ο蟮腢 鎖。對象加了U鎖,允許其他事務(wù)對它加S鎖。在最后寫入時(shí),再申請將U鎖升級為X鎖。不必在全過程中加X
不同級別的加鎖協(xié)議
一級封鎖協(xié)議(臟數(shù)據(jù)、不可重復(fù)讀)
任一事務(wù)在寫某數(shù)據(jù)前,必須對其加上X鎖,該事務(wù)結(jié)束后才釋放。不采用S鎖,讀數(shù)據(jù)不用加鎖。
事務(wù)結(jié)束包括正常結(jié)束(COMMIT)和非正常結(jié)束(ROLLBACK)。
二級封鎖協(xié)議(不可重復(fù)讀)
滿足一級封鎖協(xié)議,且任一事務(wù)在讀取某數(shù)據(jù)前,必須對其加上S鎖,讀完后 就釋放
三級封鎖協(xié)議()
滿足一級封鎖協(xié)議,且任一事務(wù)在讀取某數(shù)據(jù)前,必須對其加上S鎖,事務(wù)結(jié)束后 釋放鎖
其他加鎖協(xié)議
兩階段加鎖協(xié)議:
整個(gè)事務(wù)分為兩個(gè)階段,前一個(gè)階段為加鎖,后一個(gè)階段為解鎖。在加鎖階段,事務(wù)只能加鎖,也可以操作數(shù)據(jù),但不能解鎖,直到事務(wù)釋放第一個(gè)鎖,就進(jìn)入解鎖階段,此過程中事務(wù)只能解鎖,也可以操作數(shù)據(jù),不能再加鎖。兩階段鎖協(xié)議使得事務(wù)具有較高的并發(fā)度,因?yàn)榻怄i不必發(fā)生在事務(wù)結(jié)尾。它的不足是沒有解決死鎖的問題,因?yàn)樗诩渔i階段沒有順序要求。如兩個(gè)事務(wù)分別申請了A, B鎖,接著又申請對方的鎖,此時(shí)進(jìn)入死鎖狀態(tài)。
定理:若所有事務(wù)均遵守兩段鎖協(xié)議,則這些事務(wù)的所有交叉調(diào)度都是可串行化的。
多粒度加鎖協(xié)議
行級鎖:開銷大,加鎖慢;會出現(xiàn)死鎖;鎖定粒度最小,發(fā)生鎖沖突的概率最低,并發(fā)度也最高。只在存儲引擎層實(shí)現(xiàn)
頁級鎖:開銷和加鎖時(shí)間界于表鎖和行鎖之間;會出現(xiàn)死鎖;鎖定粒度界于表鎖和行鎖之間,并發(fā)度一般
表級鎖:開銷小,加鎖快;不會出現(xiàn)死鎖;鎖定粒度大,發(fā)生鎖沖突的概率最高,并發(fā)度最低。