1.并發(fā)沖突
當(dāng)兩個(gè)進(jìn)程試圖在同一時(shí)間修改同一數(shù)據(jù),就會(huì)產(chǎn)生沖突。
2.并發(fā)控制
有兩種方式管理并發(fā)數(shù)據(jù)訪問(wèn):樂(lè)觀并發(fā)控制、悲觀并發(fā)控制。
這兩種控制模式的區(qū)別在于,是在沖突發(fā)生前進(jìn)行防止,還是在發(fā)生后采用某種方法來(lái)處理沖突。
3.悲觀并發(fā)控制
悲觀并發(fā)模式假定系統(tǒng)中存在足夠多的數(shù)據(jù)修改操作,以致任何確定的讀操作都可能會(huì)受到由別的用戶所制造的數(shù)據(jù)修改的影響。
也就是說(shuō),悲觀并發(fā)模式假定沖突總是會(huì)發(fā)生的。
悲觀并發(fā)控制是通過(guò)獨(dú)占正在被讀取的數(shù)據(jù)來(lái)避免沖突。
但是獨(dú)占數(shù)據(jù)會(huì)導(dǎo)致其它進(jìn)程無(wú)法修改該數(shù)據(jù),進(jìn)而產(chǎn)生阻塞——讀數(shù)據(jù)和寫數(shù)據(jù)會(huì)互相阻塞。
4.樂(lè)觀并發(fā)控制
樂(lè)觀并發(fā)模式假定系統(tǒng)的數(shù)據(jù)修改操作只會(huì)生產(chǎn)非常少的沖突,也就是說(shuō)任何進(jìn)程都不太可能修改別的進(jìn)程正在訪問(wèn)的數(shù)據(jù)。
樂(lè)觀并發(fā)模式下,讀數(shù)據(jù)和寫數(shù)據(jù)之間不會(huì)發(fā)生沖突,只有寫數(shù)據(jù)與寫數(shù)據(jù)之間會(huì)發(fā)生沖突。即讀數(shù)據(jù)不會(huì)產(chǎn)生阻塞,只有寫數(shù)據(jù)才會(huì)產(chǎn)生阻塞。
5.并發(fā)沖突生產(chǎn)的問(wèn)題
5.1.丟失更新(Lost updates)
兩個(gè)進(jìn)程同時(shí)讀取一筆數(shù)據(jù),然后進(jìn)行修改,那么后提交的數(shù)據(jù)會(huì)覆蓋先提交的數(shù)據(jù)。
如果數(shù)據(jù)允許覆蓋式更新(比如用戶姓名),那么丟失更新并不算太大的問(wèn)題,如果數(shù)據(jù)是累加式更新(比如庫(kù)存數(shù)量),那么丟失更新是非常嚴(yán)重的問(wèn)題,并且在非并發(fā)模式下無(wú)法重復(fù)問(wèn)題的發(fā)生。
5.2.臟讀(Dirty reads)
當(dāng)一個(gè)進(jìn)程更新了數(shù)據(jù),但(事務(wù))未提交,這時(shí)候另一個(gè)進(jìn)程讀取同一筆數(shù)據(jù),如果前一個(gè)進(jìn)程取消了更新(事務(wù)回滾),那么后一個(gè)進(jìn)程讀取的就是臟數(shù)據(jù)。
臟讀會(huì)產(chǎn)生嚴(yán)重的問(wèn)題,在任何情況下都是不允許的。
5.3.不可重復(fù)讀(Non-repeatable reads)
當(dāng)一個(gè)進(jìn)程讀取了一筆數(shù)據(jù)后,另一個(gè)進(jìn)程更新了同一筆數(shù)據(jù),然后第一個(gè)進(jìn)程再次讀取同一筆數(shù)據(jù),卻得到了與第一次讀取不同的結(jié)果。
在事務(wù)A更新記錄之后(update Customers set Name = 'B' where Name = 'A'),事務(wù)B讀取相同記錄(select Name form Customers where Name = 'A'),但事務(wù)B拿到的是事務(wù)A更新之后的數(shù)據(jù)(Customers.Name的值為'B'),在事務(wù)B讀取記錄之后,事務(wù)A進(jìn)行了事務(wù)回滾(Customers.Name的值為'A'),導(dǎo)致事務(wù)B的數(shù)據(jù)是不真實(shí)的。
5.4.幻讀(Phantoms)
幻讀與臟讀的相似之處在于:兩者都是兩次讀取的結(jié)果不一致。
不同之處在于:幻讀是兩次讀取的記錄數(shù)量不一致,而臟讀是兩次讀取的記錄的數(shù)據(jù)不一致。
事務(wù)A讀取記錄之后(select * from Customers where Name like 'A%'),事務(wù)B又插入了符合事務(wù)A讀取條件的新記錄(insert into Customers(Name) values('AAA')),那么當(dāng)事務(wù)A再用相同條件讀取記錄時(shí),得到的集合卻與上一次讀取不同(多了記錄)。
6.隔離級(jí)別
SQL Server2005支持5種隔離級(jí)別來(lái)控制沖突。其中三種只在悲觀并發(fā)模式中使用,一種只在樂(lè)觀并發(fā)模式中使用,另一個(gè)可以在兩種模式中使用。
6.1.未提交讀(Uncommitted Read)
未提交讀只能防止“丟失更新”問(wèn)題,其它問(wèn)題不能防止。
未提交讀是針對(duì)阻塞太頻繁的悲觀并發(fā)控制,因?yàn)樗皇呛雎粤随i,而不保障事務(wù)的一致性。
6.2.已提交讀(Read Committed)
已提交讀既可以是樂(lè)觀的也可以是悲觀的,這取決于數(shù)據(jù)庫(kù)的read_committed_snapshot設(shè)置。默認(rèn)情況下這個(gè)選項(xiàng)是關(guān)閉的,所以該隔離級(jí)別默認(rèn)情況下是采用悲觀并發(fā)控制。
已提交讀可以防止臟讀問(wèn)題。
6.3.可重復(fù)讀(Repeatable Read)
可重復(fù)讀是一種悲觀的隔離級(jí)別。它在已提交讀的基礎(chǔ)上增加了新特性:確保當(dāng)事務(wù)重新訪問(wèn)數(shù)據(jù)或查詢被再一次執(zhí)行時(shí),數(shù)據(jù)將不會(huì)再發(fā)生改變。
可重復(fù)讀不但可以防止臟讀問(wèn)題,還可以防止不可重復(fù)讀問(wèn)題,但是不能防止幻讀問(wèn)題。
注意,可重復(fù)讀的資源開(kāi)銷是很大的,事務(wù)中所有的數(shù)據(jù)必須等待事務(wù)完成之后才能訪問(wèn)。
6.4.快照(Snapshot)
快照是一種樂(lè)觀隔離級(jí)別。
Snapshot事務(wù)中任何語(yǔ)句所讀取的記錄,都是事務(wù)啟動(dòng)時(shí)的數(shù)據(jù)。
這相當(dāng)于事務(wù)啟動(dòng)時(shí),數(shù)據(jù)庫(kù)為事務(wù)生成了一份專用“快照”。
在當(dāng)前事務(wù)中看到不其它事務(wù)在當(dāng)前事務(wù)啟動(dòng)之后所進(jìn)行的數(shù)據(jù)修改。
Snapshot事務(wù)不會(huì)讀取記錄時(shí)要求鎖定,讀取記錄的Snapshot事務(wù)不會(huì)鎖住其它事務(wù)寫入記錄,寫入記錄的事務(wù)也不會(huì)鎖住Snapshot事務(wù)讀取數(shù)據(jù)。
快照隔離級(jí)別的事務(wù)不是串行執(zhí)行的,兩個(gè)進(jìn)程同時(shí)使用快照隔離,如果它們執(zhí)行多次,可能最終產(chǎn)生的結(jié)果不會(huì)一致。(這段話要證實(shí))
6.5.可串行化(Serializable)
可串行化是一種悲觀隔離級(jí)別。它在可重復(fù)讀的基礎(chǔ)上增加了新的特性:確保在兩次查詢的中間,不會(huì)增加新的行。
可串行化是最健壯的悲觀隔離級(jí)別,因?yàn)樗乐沽瞬l(fā)沖突產(chǎn)生的4個(gè)問(wèn)題。
可串行化也是資源開(kāi)銷最大的措施。當(dāng)使用可串行化隔離時(shí),如果SQL的條件字段沒(méi)有索引,那么SQL Server會(huì)產(chǎn)生表級(jí)鎖。
6.6.總結(jié)
7.鎖
7.1.死鎖
當(dāng)二或多個(gè)工作各自具有某個(gè)資源的鎖定,但其它工作嘗試要鎖定此資源,而造成工作永久封鎖彼此時(shí),會(huì)發(fā)生死鎖。例如:
1.事務(wù)A取得數(shù)據(jù)列1的共享鎖定。
2.事務(wù)B取得數(shù)據(jù)列2的共享鎖定。
3.事務(wù)A現(xiàn)在要求數(shù)據(jù)列2的獨(dú)占鎖定,但會(huì)被封鎖直到事務(wù)B完成并釋出對(duì)數(shù)據(jù)列2的共享鎖定為止。
4.事務(wù)B現(xiàn)在要求數(shù)據(jù)列1的獨(dú)占鎖定,但會(huì)被封鎖直到事務(wù)A完成并釋出對(duì)數(shù)據(jù)列1的共享鎖定為止。
等到事務(wù)B完成后,事務(wù)A才能完成,但事務(wù)B被事務(wù)A封鎖了。這個(gè)狀況也稱為「循環(huán)相依性」(Cyclic Dependency)。事務(wù)A相依于事務(wù)B,并且事務(wù)B也因?yàn)橄嘁烙谑聞?wù)A而封閉了這個(gè)循環(huán)。
例如以下操作就會(huì)產(chǎn)生死鎖,兩個(gè)連接互相阻塞對(duì)方的update。
連接1:
begin tran
select * from customers
update customers set CompanyName = CompanyName
select * from Employees
–因?yàn)镋mployees被連接2鎖住了,所以這里會(huì)阻塞。
update Employees set LastName = LastName
commit tran
連接2:
begin tran
select * from Employees
update Employees set LastName = LastName
waitfor delay '00:00:05'
select * from customers
--因?yàn)閏ustomers被連接1鎖住了,所以這里會(huì)阻塞。
update customers set CompanyName = CompanyName
commit tran
SQL Server遇到死鎖時(shí)會(huì)自動(dòng)殺死其中一個(gè)事務(wù),而另一個(gè)事務(wù)會(huì)正常結(jié)束(提交或回滾)。
SQL Server對(duì)殺死的連接返回錯(cuò)誤代碼是1205,異常提示是:
Your transaction (process ID #52) was deadlocked on {lock | communication buffer | thread} resources with another process and has been chosen as the deadlock victim. Rerun your transaction.
除了Read Uncommitted和Snapshot,其它類型的事務(wù)都可能產(chǎn)生死鎖。
7.2.悲觀鎖
悲觀鎖是指假設(shè)并發(fā)更新沖突會(huì)發(fā)生,所以不管沖突是否真的發(fā)生,都會(huì)使用鎖機(jī)制。
悲觀鎖會(huì)完成以下功能:鎖住讀取的記錄,防止其它事務(wù)讀取和更新這些記錄。其它事務(wù)會(huì)一直阻塞,直到這個(gè)事務(wù)結(jié)束。
悲觀鎖是在使用了數(shù)據(jù)庫(kù)的事務(wù)隔離功能的基礎(chǔ)上,獨(dú)享占用的資源,以此保證讀取數(shù)據(jù)一致性,避免修改丟失。
悲觀鎖可以使用Repeatable Read事務(wù),它完全滿足悲觀鎖的要求。
7.3.樂(lè)觀鎖
樂(lè)觀鎖不會(huì)鎖住任何東西,也就是說(shuō),它不依賴數(shù)據(jù)庫(kù)的事務(wù)機(jī)制,樂(lè)觀鎖完全是應(yīng)用系統(tǒng)層面的東西。
如果使用樂(lè)觀鎖,那么數(shù)據(jù)庫(kù)就必須加版本字段,否則就只能比較所有字段,但因?yàn)楦↑c(diǎn)類型不能比較,所以實(shí)際上沒(méi)有版本字段是不可行的。
7.4.悲觀離線鎖
悲觀離線鎖是應(yīng)用程序級(jí)別的機(jī)制,它是由應(yīng)用程序?qū)崿F(xiàn)的,不是數(shù)據(jù)庫(kù)實(shí)現(xiàn)的。
-
死鎖
+關(guān)注
關(guān)注
0文章
25瀏覽量
8200 -
并發(fā)控制機(jī)制
+關(guān)注
關(guān)注
0文章
2瀏覽量
5672
發(fā)布評(píng)論請(qǐng)先 登錄
第三屆大會(huì)回顧第3期 | FFRT并發(fā)框架在OpenHarmony中的設(shè)計(jì)與實(shí)踐

鴻蒙5開(kāi)發(fā)寶藏案例分享---應(yīng)用并發(fā)設(shè)計(jì)
HarmonyOS實(shí)戰(zhàn):一招解決等待多個(gè)并發(fā)結(jié)果

Ingress網(wǎng)關(guān)高并發(fā)請(qǐng)求的解決方案
【道生物聯(lián)TKB-620開(kāi)發(fā)板試用】定期休眠并發(fā)布數(shù)據(jù)
RAKsmart服務(wù)器如何重塑AI高并發(fā)算力格局
TurMass? 如何幫助解決 UWB 定位系統(tǒng)大規(guī)模終端標(biāo)簽高并發(fā)通信沖突問(wèn)題?

RK3568驅(qū)動(dòng)指南|第三篇-并發(fā)與競(jìng)爭(zhēng)-第19章 并發(fā)與競(jìng)爭(zhēng)實(shí)驗(yàn)

星型組網(wǎng)對(duì)并發(fā)用戶有限制嗎?
一文詳解CMP并發(fā)多協(xié)議

測(cè)試聊并發(fā)-入門篇

旋轉(zhuǎn)編碼器可以收集并發(fā)出什么信號(hào),旋轉(zhuǎn)編碼器信號(hào)異常怎么處理
全雙工多路并發(fā)、低延時(shí)數(shù)傳解決行業(yè)信號(hào)擁堵問(wèn)題

高并發(fā)物聯(lián)網(wǎng)云平臺(tái)是什么
高并發(fā)系統(tǒng)的藝術(shù):如何在流量洪峰中游刃有余

評(píng)論