鍍金池/ 問(wèn)答/數(shù)據(jù)庫(kù)/ 問(wèn)一個(gè)數(shù)據(jù)庫(kù)樂(lè)觀鎖的問(wèn)題

問(wèn)一個(gè)數(shù)據(jù)庫(kù)樂(lè)觀鎖的問(wèn)題

通常我們采用引入一個(gè)version版本號(hào)來(lái)作為樂(lè)觀鎖,提交的時(shí)候校驗(yàn)這個(gè)版本號(hào),那么此時(shí)有兩種方式

方式一,程序中對(duì)版本加一,即判斷條件為數(shù)據(jù)庫(kù)版本小于當(dāng)前傳入的版本:
update set name = ${name} and version = ${version} where id = ${id} and version < ${version}

方式二,通過(guò)數(shù)據(jù)庫(kù)進(jìn)行加一,即判斷條件為數(shù)據(jù)庫(kù)版本等于當(dāng)前傳入的版本:
update set name = ${name} and version = version + 1 where id = ${id} and version = ${version}

請(qǐng)問(wèn)下,這兩種方式有什么不同嗎,因?yàn)槲铱磶缀跛械臉?lè)觀鎖都是用第二種方式來(lái)實(shí)現(xiàn)的

回答
編輯回答
囍槑

個(gè)人覺(jué)得可以從并發(fā)角度來(lái)理解,如:原version值為1,同時(shí)發(fā)生了兩個(gè)更新請(qǐng)求,version都是2,語(yǔ)句一的后果可能是兩次更新后,version是2,語(yǔ)句二的后果應(yīng)該是兩次更新后,version是3。

語(yǔ)句一和語(yǔ)句二的另一個(gè)差別在于,語(yǔ)句一表示只要當(dāng)前version比原version大即可更新,而語(yǔ)句二表示必須基于某一指定version才能更新,如:原version為1,語(yǔ)句一表示當(dāng)前version無(wú)論是2還是5都可以更新,而語(yǔ)句二表示只有傳入更新條件中舊版本號(hào)為1才能更新。不過(guò)這點(diǎn)的好處我倒是沒(méi)看出來(lái)。

2018年5月31日 02:50
編輯回答
只愛(ài)你

假設(shè)用戶1和用戶2同時(shí)獲得數(shù)據(jù)version=1,并提交更新,用戶1提交的version=2,用戶2提交的version=3。

那么用第一種方法,用戶1更新完數(shù)據(jù)后,用戶2的數(shù)據(jù)會(huì)覆蓋掉用戶1的數(shù)據(jù);
而用第二種方法,用戶2更新時(shí),發(fā)現(xiàn)version已經(jīng)是2了,那么他就提交失敗了,或者重新獲取數(shù)據(jù)。

2017年3月8日 17:30
編輯回答
落殤

結(jié)果是一樣的,方法二比較好理解點(diǎn)罷了。

很多情況下,樂(lè)觀鎖并不需要version,比如你要UPDATE的是name這一列,那就可以把name當(dāng)成version,這樣就可以寫成:

UPDATE ... SET name = ${newname} WHERE id = ${id} AND name = ${oldname}

我也不知道用方法一該怎么來(lái)寫呢。

2017年12月20日 17:12