鍍金池/ 問答/數(shù)據(jù)庫/ 問一個數(shù)據(jù)庫樂觀鎖的問題

問一個數(shù)據(jù)庫樂觀鎖的問題

通常我們采用引入一個version版本號來作為樂觀鎖,提交的時候校驗這個版本號,那么此時有兩種方式

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

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

請問下,這兩種方式有什么不同嗎,因為我看幾乎所有的樂觀鎖都是用第二種方式來實現(xiàn)的

回答
編輯回答
囍槑

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

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

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

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

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

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

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

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

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

我也不知道用方法一該怎么來寫呢。

2017年12月20日 17:12