色尼玛亚洲综合影院,亚洲3atv精品一区二区三区,麻豆freexxxx性91精品,欧美在线91

不用鎖表,沒(méi)有異常:在高并發(fā)網(wǎng)絡(luò)中高效的更新數(shù)據(jù)庫(kù)數(shù)據(jù)的方式

很多Web系統(tǒng)的瓶頸在網(wǎng)絡(luò)IO,所以很多系統(tǒng)都采用多Web服務(wù)器負(fù)載均衡,雙DB做雙機(jī)熱備(其實(shí)就是只有一個(gè)DB,兩臺(tái)只有一臺(tái)真正工作,死掉一臺(tái)另一臺(tái)頂上)的方式部署,在這個(gè)時(shí)候很多原本不是問(wèn)題的系統(tǒng)也會(huì)產(chǎn)生很多的問(wèn)題。

這里我們假設(shè)有表Product,其定義如下:

列明

類型

說(shuō)明

Id

Int

自增字段,實(shí)例的ID

ProductName

Varchar(100)

商品的名稱

StoreCount

int

庫(kù)存數(shù)量

。。。

。。。

。。。

 

假設(shè)很不湊巧的,3個(gè)管理員P1,P2,P3同時(shí)操作了這個(gè)表,且P1 update StoreCount=50,P2 update StoreCount=49,P3 update StoreCount=48。這個(gè)時(shí)候問(wèn)題就來(lái)了,如果是讓他們都同時(shí)提交進(jìn)去,當(dāng)然沒(méi)問(wèn)題,但是如果這個(gè)時(shí)候N個(gè)Web程序在讀的時(shí)候就會(huì)產(chǎn)生每臺(tái)服務(wù)器上讀出來(lái)的數(shù)據(jù)都可能不一樣,A服務(wù)器讀出來(lái)是48B服務(wù)器讀出來(lái)是50C服務(wù)器讀出來(lái)是49

 

如果我們采用數(shù)據(jù)庫(kù)鎖可以避免這個(gè)問(wèn)題,但是隨之而來(lái)的是系統(tǒng)效率降低和無(wú)可避免的異常,而hibernate等實(shí)現(xiàn)的樂(lè)觀鎖呢,呵呵,對(duì)不起了,在多Web服務(wù)器的時(shí)候還能起作用嗎?

 

由此產(chǎn)生了以下的解決方案:

和樂(lè)觀鎖的實(shí)現(xiàn)相反,我們不反對(duì)任何一個(gè)客戶端的提交,樂(lè)觀鎖對(duì)讀取的數(shù)據(jù)增加版本號(hào),那么這個(gè)解決方案中對(duì)提交的數(shù)據(jù)增加“版本號(hào)”其實(shí)也就是時(shí)間戳。針對(duì)上面的Product表作為例子,為了實(shí)現(xiàn)無(wú)鎖的提交,我們需要增加一個(gè)表Product_Dirty,以后我們將稱其為臟表,Product表我們稱之為主表。臟表的結(jié)構(gòu)和主表幾乎完全一致,只是增加了一個(gè)時(shí)間戳字段用于記錄詳細(xì)的插入時(shí)間:

列明

類型

說(shuō)明

Timespan

Int

時(shí)間戳,精確到毫秒(能到納秒更好)

Id

Int

實(shí)例的ID(這里就不是自增字段了)

ProductName

Varchar(100)

商品的名稱

StoreCount

int

庫(kù)存數(shù)量

。。。

。。。

。。。

 

在發(fā)生任何update的時(shí)候都將數(shù)據(jù)直接插入這個(gè)表,不要猶疑,沒(méi)鎖,所以可以快速的,盡情的插入數(shù)據(jù)。這里還是保持最初的假設(shè),P1P2P3同時(shí)修改,所以插入了三條數(shù)據(jù)。所謂的同時(shí)插入其實(shí)在毫秒這個(gè)級(jí)別還是有差距的,所以三條記錄的時(shí)間戳是不同的。好了這個(gè)時(shí)候數(shù)據(jù)進(jìn)來(lái)了,但是主表的列數(shù)據(jù)還是沒(méi)有改變,先在假設(shè)A服務(wù)器BC服務(wù)器都同時(shí)開(kāi)始讀數(shù)據(jù)了。在主表的時(shí)候,如果發(fā)現(xiàn)臟表有數(shù)據(jù)則表明主表數(shù)據(jù)為臟(已經(jīng)修改過(guò)了)這個(gè)時(shí)候我們就開(kāi)始合并數(shù)據(jù),當(dāng)然這個(gè)操作是需要在一個(gè)事務(wù)里實(shí)現(xiàn)。合并的操作其實(shí)很簡(jiǎn)單,就是取時(shí)間戳最大的(也就是最近一次修改)更新主表的數(shù)據(jù),同時(shí)刪掉臟表里的和主表ID相等的所有數(shù)據(jù)。如果發(fā)現(xiàn)主表關(guān)聯(lián)的臟表沒(méi)數(shù)據(jù),那么就說(shuō)明主表數(shù)據(jù)正常,就直接讀取主表的內(nèi)容。

 

此解決方案來(lái)自電信營(yíng)帳系統(tǒng)的設(shè)計(jì),由于省電信眾多系統(tǒng)都是由分布很廣的地市州電信業(yè)務(wù)人員操作,所以修改的時(shí)候經(jīng)常存在本文要解決的問(wèn)題,由于操作的人多,鎖表的話會(huì)造成嚴(yán)重的擁塞,故產(chǎn)生了這個(gè)解決方案,由于電信的業(yè)務(wù)需要后臺(tái)跑了一個(gè)服務(wù)來(lái)合并數(shù)據(jù),并且每秒定時(shí)運(yùn)行,故每秒為一個(gè)業(yè)務(wù)周期。我將其修改成在讀取的時(shí)候合并,更加靈活一些。

 

好處:不用鎖表,樂(lè)觀鎖也不用,可以在N服務(wù)器操作的時(shí)候使用,且大家都不會(huì)報(bào)錯(cuò),簡(jiǎn)化了異常處理。

 

壞處:增加了表,結(jié)構(gòu)復(fù)雜,如果是用于修改原有業(yè)務(wù)如果只是幾個(gè)關(guān)鍵表的話還好,全部都采用這個(gè)方式工作量巨大(好在電信不缺錢)。

 

弱點(diǎn):和樂(lè)觀鎖類似,在某些場(chǎng)景下仍然可能臟讀,所以如果對(duì)這方面有很高的要求,還是用悲觀鎖吧。

 

it知識(shí)庫(kù)不用鎖表,沒(méi)有異常:在高并發(fā)網(wǎng)絡(luò)中高效的更新數(shù)據(jù)庫(kù)數(shù)據(jù)的方式,轉(zhuǎn)載需保留來(lái)源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 稷山县| 铜川市| 翁牛特旗| 林周县| 墨竹工卡县| 株洲县| 朝阳区| 青田县| 昌平区| 黄平县| 介休市| 共和县| 新乡市| 云龙县| 云阳县| 南通市| 斗六市| 武鸣县| 黄陵县| 丹阳市| 六枝特区| 广宗县| 凌海市| 临湘市| 眉山市| 聂荣县| 罗定市| 慈利县| 灵山县| 奉贤区| 平泉县| 牙克石市| 江华| 南江县| 鄂托克旗| 阿拉尔市| 临洮县| 崇明县| 杨浦区| 宝山区| 新郑市|