樂觀鎖以及樂觀鎖的實(shí)現(xiàn)
一、為什么需要鎖(并發(fā)控制)? 在多用戶環(huán)境中,在同一時(shí)間可能會(huì)有多個(gè)用戶更新相同的記錄,這會(huì)產(chǎn)生沖突。這就是著名的并發(fā)性問題。 典型的沖突有: 1.丟失更新:一個(gè)事務(wù)的更新覆蓋了其它事務(wù)的更新結(jié)果,就是所謂的更新丟失。例如:用戶A把值從6改為2,用戶B把值從2改為6,則用戶A丟失了他的更新。 2.臟讀:當(dāng)一個(gè)事務(wù)讀取其它完成一半事務(wù)的記錄時(shí),就會(huì)發(fā)生臟讀取。例如:用戶A,B看到的值都是6,用戶B把值改為2,用戶A讀到的值仍為6。
為了解決這些并發(fā)帶來的問題。 我們需要引入并發(fā)控制機(jī)制。
二、 并發(fā)控制機(jī)制
鎖,即給我們選定的目標(biāo)數(shù)據(jù)上鎖,使其無法被其他程序修改。
1.悲觀鎖:指的是對(duì)數(shù)據(jù)被外界(包括本系統(tǒng)當(dāng)前的其他事務(wù),以及來自外部系統(tǒng)的事務(wù)處理)修改持保守態(tài)度,因此,在整個(gè)數(shù)據(jù)處理過程中,將數(shù)據(jù)處于鎖定狀態(tài) 2.樂觀鎖:假設(shè)不會(huì)發(fā)生并發(fā)沖突,只在提交操作時(shí)檢查是否違反數(shù)據(jù)完整性。樂觀鎖不能解決臟讀的問題。
三、樂觀鎖的實(shí)現(xiàn) 使用數(shù)據(jù)版本(Version)記錄機(jī)制實(shí)現(xiàn),這是樂觀鎖最常用的一種實(shí)現(xiàn)方式。何謂數(shù)據(jù)版本?即為數(shù)據(jù)增加一個(gè)版本標(biāo)識(shí),一般是通過為數(shù)據(jù)庫(kù)表增加一個(gè)數(shù)字類型的 “version” 字段來實(shí)現(xiàn)。當(dāng)讀取數(shù)據(jù)時(shí),將version字段的值一同讀出,數(shù)據(jù)每更新一次,對(duì)此version值加一。當(dāng)我們提交更新的時(shí)候,判斷數(shù)據(jù)庫(kù)表對(duì)應(yīng)記錄的當(dāng)前版本信息與第一次取出來的version值進(jìn)行比對(duì),如果數(shù)據(jù)庫(kù)表當(dāng)前版本號(hào)與第一次取出來的version值相等,則予以更新,否則認(rèn)為是過期數(shù)據(jù)
1.數(shù)據(jù)庫(kù)表設(shè)計(jì)
task
有三個(gè)字段,分別是id,value、version
2.實(shí)現(xiàn)
1)先讀task表的數(shù)據(jù)(實(shí)際上這個(gè)表只有一條記錄),得到version的值為versionValue
2)每次更新task表中的value字段時(shí),為了防止發(fā)生沖突,需要這樣操作
update task set value = newValue,version = versionValue + 1 where version = versionValue;
只有這條語句執(zhí)行了,才表明本次更新value字段的值成功
如假設(shè)有兩個(gè)節(jié)點(diǎn)A和B都要更新task表中的value字段值,差不多在同一時(shí)刻,A節(jié)點(diǎn)和B節(jié)點(diǎn)從task表中讀到的version值為2,那么A節(jié)點(diǎn)和B節(jié)點(diǎn)在更新value字段值的時(shí)候,都操作 update task set value = newValue,version = 3 where version = 2;,實(shí)際上只有1個(gè)節(jié)點(diǎn)執(zhí)行該SQL語句成功,假設(shè)A節(jié)點(diǎn)執(zhí)行成功,那么此時(shí)task表的version字段的值是3,B節(jié)點(diǎn)再操作update task set value = newValue,version = 3 where version = 2;這條SQL語句是不執(zhí)行的,這樣就保證了更新task表時(shí)不發(fā)生沖突
頂2新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注