谈谈mysql的悲观和乐观锁 - 周伯通的麦田 - 博客园
悲觀鎖與樂(lè)觀鎖是兩種常見(jiàn)的資源并發(fā)鎖設(shè)計(jì)思路,也是并發(fā)編程中一個(gè)非常基礎(chǔ)的概念。之前有寫過(guò)一篇文章關(guān)于并發(fā)的處理思路和解決方案,這里我單獨(dú)將對(duì)這兩種常見(jiàn)的鎖機(jī)制在數(shù)據(jù)庫(kù)數(shù)據(jù)上的實(shí)現(xiàn)進(jìn)行比較系統(tǒng)的介紹一次吧。
悲觀鎖(Pessimistic Lock)悲觀鎖的特點(diǎn)是先獲取鎖,再進(jìn)行業(yè)務(wù)操作,即“悲觀”的認(rèn)為獲取鎖是非常有可能失敗的,因此要先確保獲取鎖成功再進(jìn)行業(yè)務(wù)操作。通常所說(shuō)的“一鎖二查三更新”即指的是使用悲觀鎖。通常來(lái)講在數(shù)據(jù)庫(kù)上的悲觀鎖需要數(shù)據(jù)庫(kù)本身提供支持,即通過(guò)常用的select … for update操作來(lái)實(shí)現(xiàn)悲觀鎖。當(dāng)數(shù)據(jù)庫(kù)執(zhí)行select for update時(shí)會(huì)獲取被select中的數(shù)據(jù)行的行鎖,因此其他并發(fā)執(zhí)行的select for update如果試圖選中同一行則會(huì)發(fā)生排斥(需要等待行鎖被釋放),因此達(dá)到鎖的效果。select for update獲取的行鎖會(huì)在當(dāng)前事務(wù)結(jié)束時(shí)自動(dòng)釋放,因此必須在事務(wù)中使用。
這里需要注意的一點(diǎn)是不同的數(shù)據(jù)庫(kù)對(duì)select for update的實(shí)現(xiàn)和支持都是有所區(qū)別的,例如oracle支持select for update no wait,表示如果拿不到鎖立刻報(bào)錯(cuò),而不是等待,mysql就沒(méi)有no wait這個(gè)選項(xiàng)。另外mysql還有個(gè)問(wèn)題是select for update語(yǔ)句執(zhí)行中所有掃描過(guò)的行都會(huì)被鎖上,這一點(diǎn)很容易造成問(wèn)題。因此如果在mysql中用悲觀鎖務(wù)必要確定走了索引,而不是全表掃描。
樂(lè)觀鎖(Optimistic Lock)樂(lè)觀鎖的特點(diǎn)先進(jìn)行業(yè)務(wù)操作,不到萬(wàn)不得已不去拿鎖。即“樂(lè)觀”的認(rèn)為拿鎖多半是會(huì)成功的,因此在進(jìn)行完業(yè)務(wù)操作需要實(shí)際更新數(shù)據(jù)的最后一步再去拿一下鎖就好。
樂(lè)觀鎖在數(shù)據(jù)庫(kù)上的實(shí)現(xiàn)完全是邏輯的,不需要數(shù)據(jù)庫(kù)提供特殊的支持。一般的做法是在需要鎖的數(shù)據(jù)上增加一個(gè)版本號(hào),或者時(shí)間戳,然后按照如下方式實(shí)現(xiàn):
1. SELECT data AS old_data, version AS old_version FROM …; 2. 根據(jù)獲取的數(shù)據(jù)進(jìn)行業(yè)務(wù)操作,得到new_data和new_version 3. UPDATE SET data = new_data, version = new_version WHERE version = old_version if (updated row > 0) {// 樂(lè)觀鎖獲取成功,操作完成 } else {// 樂(lè)觀鎖獲取失敗,回滾并重試 }總結(jié)
樂(lè)觀鎖在不發(fā)生取鎖失敗的情況下開銷比悲觀鎖小,但是一旦發(fā)生失敗回滾開銷則比較大,因此適合用在取鎖失敗概率比較小的場(chǎng)景,可以提升系統(tǒng)并發(fā)性能
樂(lè)觀鎖還適用于一些比較特殊的場(chǎng)景,例如在業(yè)務(wù)操作過(guò)程中無(wú)法和數(shù)據(jù)庫(kù)保持連接等悲觀鎖無(wú)法適用的地方
無(wú)論從事什么行業(yè),只要做好兩件事就夠了,一個(gè)是你的專業(yè)、一個(gè)是你的人品,專業(yè)決定了你的存在,人品決定了你的人脈,剩下的就是堅(jiān)持,用善良專業(yè)和真誠(chéng)贏取更多的信任。不忘初心 方得始終!
總結(jié)
以上是生活随笔為你收集整理的谈谈mysql的悲观和乐观锁 - 周伯通的麦田 - 博客园的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Linux系统编程2.文件
- 下一篇: mysql使用需要钱吗_SQL Serv