日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

数据库中的悲观锁和乐观锁

發(fā)布時(shí)間:2023/12/20 数据库 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据库中的悲观锁和乐观锁 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

現(xiàn)在我們簡(jiǎn)單聊一下數(shù)據(jù)庫(kù)中的悲觀鎖和樂(lè)觀鎖。

悲觀鎖

悲觀鎖正如其名稱,比較悲觀。總會(huì)認(rèn)為:每當(dāng)修改數(shù)據(jù)時(shí),會(huì)有其他線程也會(huì)同時(shí)修改該數(shù)據(jù)。所以針對(duì)這種情況悲觀鎖的做法是:讀取數(shù)據(jù)之后就加鎖(eg: select...for update),這樣別的線程讀取該數(shù)據(jù)的時(shí)候就需要等待當(dāng)前線程釋放鎖,獲得到鎖的線程才能獲得該數(shù)據(jù)的讀寫(xiě)權(quán)限。從而保證了并發(fā)修改數(shù)據(jù)錯(cuò)誤的問(wèn)題。但是由于阻塞原因,所以導(dǎo)致吞吐量不高。悲觀鎖更適用于多寫(xiě)少讀的情況。

場(chǎng)景: 同學(xué)A和同學(xué)B都要給你轉(zhuǎn)500塊錢(qián)(開(kāi)心壞了吧,這樣最終你能得到1000塊錢(qián))。

使用悲觀鎖的流程:

  • 同學(xué)A獲取到你的賬戶余額balance = 0并對(duì)該條記錄加鎖。
  • 同學(xué)B獲取你的賬戶余額。由于同學(xué)A已經(jīng)對(duì)這條記錄加鎖了,所以同學(xué)B需要等同學(xué)A轉(zhuǎn)帳完成(釋放鎖)才能獲得余額。
  • 同學(xué)A轉(zhuǎn)賬完成并釋放鎖,此時(shí)你的賬戶余額balance=balance + 500 = 500
  • 同學(xué)B獲取到你的賬戶余額balance = 500,并對(duì)該條記錄加鎖(如果你人緣好,此時(shí)同學(xué)C給你轉(zhuǎn)賬也是需要等待同學(xué)B轉(zhuǎn)賬完成才可以轉(zhuǎn)賬哦)
  • 同學(xué)B轉(zhuǎn)賬完成并釋放鎖(如果有同學(xué)C想給你轉(zhuǎn)賬,此時(shí)同學(xué)C就可以獲得鎖并轉(zhuǎn)賬了)。此時(shí)你的賬戶余額為balance = balance + 500 = 1000
  • 最終你開(kāi)開(kāi)心心的得到了1000塊錢(qián)。
  • 假設(shè)轉(zhuǎn)賬過(guò)程沒(méi)有鎖,我們看看會(huì)發(fā)生什么:

  • 同學(xué)A獲取到你的賬戶余額balance_a = 0(沒(méi)有加鎖,此時(shí)同學(xué)B也可以獲取到賬戶余額)
  • 同學(xué)B獲取到你的賬戶余額balance_b = 0
  • 同學(xué)A轉(zhuǎn)賬完成,此時(shí)你的賬戶余額為balance = balance_a + 500 = 500
  • 同學(xué)B轉(zhuǎn)賬完成,此時(shí)你的賬戶余額為balance = balance_b + 500 = 500
  • 最終同學(xué)A和同學(xué)B都轉(zhuǎn)了500,但是你最終只獲得了500。這一定是不能接受的吧。
  • 丟失的500塊去哪里了呢?從第2步可以看到同學(xué)B獲取到的賬戶余額是0,而不是同學(xué)A轉(zhuǎn)帳之后的余額500。所以問(wèn)題出在這里,這是高并發(fā)場(chǎng)景的常見(jiàn)問(wèn)題。所以加鎖是非常必須的。但是加了悲觀鎖,同學(xué)都要排隊(duì)給我轉(zhuǎn)賬,對(duì)于沒(méi)有耐心的同學(xué)就直接不轉(zhuǎn)帳了,我豈不是錯(cuò)失了發(fā)財(cái)?shù)暮脵C(jī)會(huì)。那有什么好辦法呢?答案就是下面的樂(lè)觀鎖

    樂(lè)觀鎖

    樂(lè)觀鎖顧名思義比較樂(lè)觀,他只有在更新數(shù)據(jù)的時(shí)候才會(huì)檢查這條數(shù)據(jù)是否被其他線程更新了(這點(diǎn)與悲觀鎖一樣,悲觀鎖是在讀取數(shù)據(jù)的時(shí)候就加鎖了)。如果更新數(shù)據(jù)時(shí),發(fā)現(xiàn)這條數(shù)據(jù)被其他線程更新了,則此次更新失敗。如果數(shù)據(jù)未被其他線程更新,則更新成功。由于樂(lè)觀鎖沒(méi)有了鎖等待,提高了吞吐量,所以樂(lè)觀鎖適合多讀少寫(xiě)的場(chǎng)景。

    常見(jiàn)的樂(lè)觀鎖實(shí)現(xiàn)方式是:版本號(hào)version和CAS(compare and swap)。此處只介紹版本號(hào)方式。

    要采用版本號(hào),首先需要在數(shù)據(jù)庫(kù)表中新增一個(gè)字段version,表示此條記錄的更新版本,記錄每變動(dòng)一次,版本號(hào)加1。依舊使用上面轉(zhuǎn)賬的例子說(shuō)明:

  • 同學(xué)A獲取到你的賬戶余額balance = 0和版本號(hào)version_a = 0
  • 同學(xué)B獲取到你的賬戶余額balance = 0和版本號(hào)version_b = 0
  • 同學(xué)A轉(zhuǎn)賬完成update table set balance = ${balance}, version = version + 1 and version = 0。(此時(shí)版本號(hào)為0,所以更新成功)
  • 同學(xué)B轉(zhuǎn)賬完成update table set balance = ${balance}, version = version + 1 and version = 0。(此時(shí)版本號(hào)為1,所以更新失敗,更新失敗之后同學(xué)B再轉(zhuǎn)一次即可)
  • 同學(xué)B重新轉(zhuǎn)帳之后,你還是美滋滋的獲得了1000。
  • 總結(jié)

    悲觀鎖:讀取時(shí)加鎖,更新完釋放鎖,再此過(guò)程中會(huì)造成其他線程阻塞,導(dǎo)致吞吐量低,適用于多寫(xiě)場(chǎng)景。

    樂(lè)觀鎖:不加鎖,只有在更新時(shí)驗(yàn)證數(shù)據(jù)是否被其他線程更新,吞吐量較高,適用于多讀場(chǎng)景。

    總結(jié)

    以上是生活随笔為你收集整理的数据库中的悲观锁和乐观锁的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。