数据库-乐观锁和悲观锁
寫在前面:
? ? 鎖根據(jù)其使用的方式可以劃分為:樂觀鎖和悲觀鎖。樂觀鎖即樂觀并發(fā)控制,悲觀鎖即悲觀并發(fā)控制,他們是處理并發(fā)控制時(shí)主要采用的技術(shù)手段。其中,悲觀鎖正是數(shù)據(jù)庫本身提供的鎖機(jī)制實(shí)現(xiàn)的。
? ? 悲觀鎖:
? ? 悲觀鎖(Pessimistic Concurrency Control)縮寫為PCC。從字面意義上理解,就是每次去拿數(shù)據(jù)的時(shí)候都認(rèn)為別人會修改,所以每次在拿數(shù)據(jù)的時(shí)候都會上鎖,這樣別人想拿這個(gè)數(shù)據(jù)就會進(jìn)入阻塞狀態(tài),直到它拿到鎖。在傳統(tǒng)的關(guān)系型數(shù)據(jù)庫里邊就用到了很多這種鎖機(jī)制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。
????它阻止一個(gè)事務(wù)以影響其他用戶的修改數(shù)據(jù)。如果一個(gè)事務(wù)執(zhí)行的操作對某一個(gè)數(shù)據(jù)應(yīng)用了鎖,那么只有當(dāng)事務(wù)釋放了鎖,其他事務(wù)才能夠執(zhí)行與鎖沖突的操作。
? ? 悲觀鎖主要應(yīng)用于數(shù)據(jù)競爭激烈的環(huán)境,以及如果發(fā)生并發(fā)沖突時(shí),對事務(wù)上鎖的成本低于讓事務(wù)回滾的情況。
? ? 樂觀鎖:
? ? 樂觀鎖(Optimistic?Concurrency Control)縮寫為OCC,從字面意義上理解,每次去拿數(shù)據(jù)的時(shí)候都認(rèn)為別人不會修改,所以不會上鎖,但是在更新的時(shí)候會判斷一下在此期間別人有沒有去更新這個(gè)數(shù)據(jù)。相對于悲觀鎖,樂觀鎖在處理數(shù)據(jù)庫時(shí),不會使用數(shù)據(jù)庫提供的鎖機(jī)制,一般事項(xiàng)樂觀鎖的的方式就是記錄數(shù)據(jù)版本。
? ? 那么什么是數(shù)據(jù)版本?就是為數(shù)據(jù)增加的一個(gè)版本標(biāo)識,在讀取數(shù)值的時(shí)候,將版本標(biāo)識一同讀出,數(shù)據(jù)每更新一次,版本標(biāo)識也會更新一次。當(dāng)我們提交數(shù)據(jù)更新時(shí),判斷數(shù)據(jù)庫表對應(yīng)的當(dāng)前版本標(biāo)識信息與第一次的版本標(biāo)識信息相比,如果相等,則會更新,如果不相等,則認(rèn)為是過期數(shù)據(jù)。例如:使用一個(gè)自增長的整數(shù)作為數(shù)據(jù)版本,比如數(shù)據(jù)版本為2,在更新提交時(shí)version=6+1,用version=7和最開始的version+1相比,如果相等,則更新,如果不相同,則認(rèn)為是過期數(shù)據(jù),也就是說可能被其他線程更新過了。
????樂觀鎖適用于多讀的應(yīng)用類型,這樣可以提高吞吐量,像數(shù)據(jù)庫如果提供類似于write_condition機(jī)制的其實(shí)都是提供的樂觀鎖。
案例分析:
????如一個(gè)金融系統(tǒng),當(dāng)某個(gè)職員讀取用戶的數(shù)據(jù),并在讀出的用戶數(shù)據(jù)的基礎(chǔ)上進(jìn)行修改時(shí)(如更改用戶帳戶余額),如果采用悲觀鎖機(jī)制,也就意味著整個(gè)操作過程中(從操作員讀出數(shù)據(jù)、開始修改直至提交修改結(jié)果的全過程),數(shù)據(jù)庫記錄始終處于加鎖狀態(tài),這樣,如果有上千條、上萬條事務(wù)并發(fā)要處理,則會影響用戶的使用效率。
? ? 而如果使用了樂觀鎖,那么讀取出數(shù)據(jù)時(shí),將此版本號一同讀出,之后更新時(shí),對此版本號+1。此時(shí),將提交數(shù)據(jù)的版本數(shù)據(jù)與數(shù)據(jù)庫表對應(yīng)記錄的當(dāng)前版本信息進(jìn)行比對。
對于上面修改用戶帳戶信息的例子而言,假設(shè)數(shù)據(jù)庫中帳戶信息表中有一個(gè)version 字段,當(dāng)前值為 1 ;?而當(dāng)前帳戶余額字段( balance )為 100元 。
1 職員 A 此時(shí)將其讀出( version=1 ),并從其帳戶余額中扣除?50(100-50 )。
2 在職員 A 操作的過程中,職員 B 也讀入此用戶信息( version=1 ),并從其帳戶余額中扣除?20(100-20 )。
3 職員 A 完成了修改工作,將數(shù)據(jù)版本號+1( version=2 ),連同帳戶扣除后余額( balance=50 ),提交至數(shù)據(jù)庫更新,此時(shí)由于提交數(shù)據(jù)版本=數(shù)據(jù)庫記錄當(dāng)前版本+1,數(shù)據(jù)會被更新,數(shù)據(jù)庫記錄 version 更新為 2 。
4 職員 B 完成了操作,也將版本號+1( version=2 )試圖向數(shù)據(jù)庫提交數(shù)據(jù)( balance=80 ),但此時(shí)比對數(shù)據(jù)庫記錄版本時(shí)發(fā)現(xiàn),職員 B 提交的數(shù)據(jù)版本號為 2 ,數(shù)據(jù)庫記錄當(dāng)前版本+1= 3 ,2不等于3,因此,職員 B 的提交被駁回。這樣,就避免了職員 B 用基于 version=1 的舊數(shù)據(jù)修改的結(jié)果覆蓋職員 A 的操作結(jié)果的可能。
????
總結(jié)
以上是生活随笔為你收集整理的数据库-乐观锁和悲观锁的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第四章 大数据之hive搭建
- 下一篇: mysql死锁的例子_GitHub -