亚洲成精品动漫久久精久,九九在线精品视频播放,黄色成人免费观看,三级成人影院,久碰久,四虎成人欧美精品在永久在线

掃一掃
關(guān)注微信公眾號

奇異的數(shù)據(jù)庫死鎖
2009-04-21   IT專家網(wǎng)

案例再現(xiàn):

  一家企業(yè)已經(jīng)部署了ERP系統(tǒng),其后臺就用到了Oracle數(shù)據(jù)庫系統(tǒng)。不過這個ERP系統(tǒng)沒有人事管理系統(tǒng)模塊。企業(yè)后來為了加強(qiáng)人事管理,故又采用了一款人事管理的系統(tǒng)。由于ERP系統(tǒng)是開源的,故通過簡單的開發(fā)就可以跟人事管理系統(tǒng)進(jìn)行集成。由于人事管理跟ERP系統(tǒng)的相關(guān)模塊基本上沒有很大的內(nèi)在聯(lián)系,所以最后只有User表是與人事管理系統(tǒng)共用的,其他都是通過視圖的形式進(jìn)行數(shù)據(jù)交流。但是當(dāng)企業(yè)開始用這個系統(tǒng)的時(shí)候,就出現(xiàn)了問題。如采購員需要維護(hù)供應(yīng)商聯(lián)系人(其需要用到User表)的時(shí)候,往往會發(fā)現(xiàn)數(shù)據(jù)庫會出現(xiàn)長時(shí)間的停頓現(xiàn)象。有時(shí)候甚至需要到第二天才能夠順利更改或者添加供應(yīng)商聯(lián)系人。

  數(shù)據(jù)庫管理員剛開始懷疑是否是服務(wù)器性能的問題。但是檢查了CPU以及內(nèi)存的使用情況來看,問題不是發(fā)生在性能上面。再經(jīng)過深入細(xì)致的調(diào)查,才發(fā)現(xiàn)是鎖沖突導(dǎo)致了User表反映的遲緩。這個人事管理系統(tǒng)本來就是人事管理人員在用,基本上就是一個單機(jī)版的系統(tǒng)。這個應(yīng)用程序在設(shè)計(jì)的時(shí)候,可能出于數(shù)據(jù)庫兼容性的考慮,故在表級別上實(shí)現(xiàn)了鎖。也就是說,即使對User表其中的一條記錄進(jìn)行修改,應(yīng)用程序也會為整個User表進(jìn)行加鎖。如此的話,當(dāng)人事管理人員在更該員工信息的話,這個表其他用戶就不能夠更改,直到人事管理人員完成更改。而由于供應(yīng)商聯(lián)系人信息其也是存儲在User表中,為此采購員就會感覺到User表會出現(xiàn)長時(shí)間的停頓顯現(xiàn)。

  問題解析:

  數(shù)據(jù)庫鎖主要是用來解決并發(fā)行訪問可能出現(xiàn)的問題。根據(jù)加鎖內(nèi)容的不同,可以在不同的級別上實(shí)現(xiàn)鎖。如可以在整個表上實(shí)現(xiàn)加鎖;也可以對特定的行實(shí)現(xiàn)加鎖。有些應(yīng)用軟件為了兼容于市場上每個基于SQL語句的數(shù)據(jù)庫,會例行公事地在表級別上而不是在航級別上鎖定資源。采用了不必要的高級別加鎖機(jī)制從而導(dǎo)致了不必要的鎖沖突。所以所在應(yīng)用程序設(shè)計(jì)的時(shí)候需要注意因?yàn)殒i設(shè)置不當(dāng)而給數(shù)據(jù)庫造成的負(fù)面影響。

  那么應(yīng)用程序的哪些不恰當(dāng)設(shè)計(jì)會增加鎖沖突發(fā)生的機(jī)率呢?根據(jù)筆者的經(jīng)驗(yàn),如果應(yīng)用程序如下幾個方面設(shè)計(jì)不當(dāng)?shù)脑?,則會大大增加鎖沖突發(fā)生的機(jī)會。

  1、事務(wù)運(yùn)行時(shí)間過長導(dǎo)致鎖沖突。這是最容易發(fā)生的情況。如在ERP系統(tǒng)中,有一個批量結(jié)束采購訂單的作業(yè)。因?yàn)樵诓少徲唵喂芾碇?,有時(shí)候會出現(xiàn)尾數(shù)的情況。如采購訂單明細(xì)中有一個產(chǎn)品,采購訂單上寫著是1998套,而中18套可是出于損耗率而考慮購買的。但是供應(yīng)商由于生產(chǎn)線的限制,其可能只供應(yīng)了1995套,即少供應(yīng)商了3套。此時(shí)由于供應(yīng)商交貨數(shù)量沒有達(dá)到采購數(shù)量,故此時(shí)系統(tǒng)中這張采購訂單或者采購訂單中的這個采購條目永遠(yuǎn)不會結(jié)束。這會導(dǎo)致管理上很大的麻煩。如采購員可能需要定期導(dǎo)一份未結(jié)案采購明細(xì)表以追蹤物料??纱藭r(shí)哪些尾數(shù)問題,會導(dǎo)致導(dǎo)出來的報(bào)表中內(nèi)容虛多。另外在根據(jù)采購單轉(zhuǎn)收貨單作業(yè)中,這些未結(jié)案的采購訂單也會老是在那個窗口中顯示,這給系統(tǒng)用戶選擇增添了一定的困難。故系統(tǒng)中設(shè)計(jì)了這個作業(yè),用來幫助用戶批量的結(jié)束采購訂單??墒沁@個程序如果設(shè)計(jì)的不好的話,會造成比較大的麻煩。因?yàn)檫@個作業(yè)其需要更新好多張表,如采購明細(xì)表、采購訂單頭表等等。而且還會涉及到比較復(fù)雜的業(yè)務(wù)邏輯,如需要判斷采購行行中的所有采購條目是否都已經(jīng)結(jié)束,只有在全部結(jié)束后程序才會更新采購訂單頭的結(jié)束碼字段,即這張采購訂單全部結(jié)束。如果所有明細(xì)沒有全部結(jié)束,還有部分產(chǎn)品沒有到料的話,那么只結(jié)束這個具體的條目,而采購訂單沒有結(jié)案。由于涉及到的表比較多、業(yè)務(wù)邏輯比較復(fù)雜,如果記錄再比較多的話,那么此時(shí)這個作業(yè)運(yùn)行就會需要比較長的時(shí)間。而在執(zhí)行這個作業(yè)的時(shí)候,系統(tǒng)會把這個作業(yè)所涉及表中的記錄鎖起來,不允許其他用戶進(jìn)行更改。此時(shí)若其他用戶需要對他們更改的話(更改同一條記錄的其他字段),就會造成鎖沖突。其他用戶必須等待這個作業(yè)完成之后才能夠更改相關(guān)的記錄。

  所以說,應(yīng)用程序設(shè)計(jì)時(shí)設(shè)計(jì)事務(wù)比較繁瑣,將使得鎖沖突的幾率大大提高。為此筆者建議各位應(yīng)用程序開發(fā)人員,在設(shè)計(jì)事務(wù)時(shí),最好能夠遵循簡短化的操作。如相關(guān)的業(yè)務(wù)邏輯、所涉及到的表等等,能夠簡單就簡單,能夠少就少。如果真的需要很多步驟才能夠完成一個事務(wù)的話,那就可以適當(dāng)考慮把這個事務(wù)分成幾個獨(dú)立的事務(wù)來完成。另外在給企業(yè)用戶培訓(xùn)的時(shí)候,最好能夠說明這個問題。建議企業(yè)員工在執(zhí)行這些事務(wù)的時(shí)候,選擇一個合適的時(shí)間。如可以讓員工在下班后執(zhí)行這個作業(yè),以降低對其他用戶的影響。

  2、由于所級別設(shè)置不當(dāng)所造成的鎖沖突。在Oracle10G以后的版本中,一個事務(wù)能夠鎖定一行、多行或者整個表。雖然用戶也可以手工對行或者表進(jìn)行加鎖,但是Oracle數(shù)據(jù)庫服務(wù)器能夠自動在盡可能低的級別上鎖定必要的行,以保證數(shù)據(jù)完整性,并最小化與其他可能需要訪問該表中其他行的事務(wù)之間的沖突。

如筆者一開始提到的案例,一些應(yīng)用軟件為了提高其軟件的兼容性,提高其軟件支持的數(shù)據(jù)庫系統(tǒng),就會例行公事的采取高級別的鎖機(jī)制。在本來只需對行進(jìn)行加鎖的情況下,而對表進(jìn)行了加鎖。這就會影響其他用戶對該表進(jìn)行維護(hù)工作。為此筆者認(rèn)為,應(yīng)用程序在設(shè)計(jì)的時(shí)候,考慮了軟件與數(shù)據(jù)庫系統(tǒng)的兼容性,那本來是件好事情。但是在設(shè)計(jì)的時(shí)候能否再到位一點(diǎn)的。如可以根據(jù)數(shù)據(jù)庫接口的不同,來考慮到底是采取行級別鎖呢還是采取表級別鎖。而不能夠一刀切,不分青紅皂白一律采用表鎖。這會大大降低應(yīng)用程序的性能,是一個不合理的設(shè)計(jì)方法。也即是說,應(yīng)用程序應(yīng)該可以根據(jù)所采用數(shù)據(jù)庫的不同(甚至版本的不同)來判斷這些數(shù)據(jù)庫是否支持行鎖。如果支持行鎖的話,則就只需要對行加鎖即可。其實(shí)要實(shí)現(xiàn)這個也不是很難,只需要在應(yīng)用程序初始化的時(shí)候進(jìn)行設(shè)置即可。先進(jìn)一點(diǎn)的直接可以從數(shù)據(jù)庫接口中獲得數(shù)據(jù)庫的品牌與版本信息,并進(jìn)行相應(yīng)的調(diào)整。遲鈍一點(diǎn)的需要系統(tǒng)管理員在初始化參數(shù)中手工指定所采用的數(shù)據(jù)庫品牌與版本。即使采取后面這種笨辦法也要比采用一刀切的表級別鎖方式好得多。

  3、沒有嚴(yán)格限制用戶從數(shù)據(jù)庫表中更新數(shù)據(jù)。

  有些軟件在設(shè)計(jì)時(shí),允許用戶可以直接在數(shù)據(jù)庫中修改相關(guān)的數(shù)據(jù)。這或許能夠給企業(yè)帶來一定的便利性,但是也會造成比較到的隱患。如某個系統(tǒng)管理員可能從數(shù)據(jù)庫表中更新了相關(guān)的數(shù)據(jù)。但是他在更新完成后,可能是出于疏忽的原因,沒有立即執(zhí)行commit語句。此時(shí)利用當(dāng)前會話進(jìn)行查詢的話,會發(fā)現(xiàn)數(shù)據(jù)已經(jīng)被更改。而利用另外一個會話查詢的時(shí)候,其查詢到的仍然是更改前的數(shù)據(jù)。也就是說,此時(shí)系統(tǒng)管理員更改的數(shù)據(jù)還沒有提交到數(shù)據(jù)庫表中。此時(shí)對于所涉及到的行就會進(jìn)行加鎖。而且有時(shí)候出于性能等方面的考慮,數(shù)據(jù)庫甚至?xí)φ麖埍磉M(jìn)行加鎖。由于用戶忘了執(zhí)行commit指令,這個鎖就會一直在那邊。那么其他用戶就不能夠?qū)@些記錄進(jìn)行任何的更改作業(yè)。#p#分頁標(biāo)題#e#

  類似的情況筆者遇到的還是比較多的。因?yàn)橛行┫到y(tǒng)管理員沒有受到過專業(yè)的數(shù)據(jù)庫培訓(xùn),是半路出家的。為此他們對于這個鎖的機(jī)制與Commit命令的功用沒有直觀的印象。所以他們從數(shù)據(jù)庫中更新數(shù)據(jù)后,往往會忘記執(zhí)行Commit命令。所以筆者認(rèn)為如果把數(shù)據(jù)庫開發(fā)給企業(yè)的話,可能對數(shù)據(jù)庫的性能會產(chǎn)生比較大的影響,因?yàn)橛脩艉苋菀淄泩?zhí)行commit指令。而如果企業(yè)用戶的更新動作都通過前臺應(yīng)用程序來完成,那么很少會發(fā)生這種情況了。在應(yīng)用程序設(shè)計(jì)的時(shí)候,肯定會在SQL語句的最后加上一個Commit指令。這就可以防止因?yàn)闆]有恰當(dāng)執(zhí)行commit指令而導(dǎo)致的鎖沖突事件的發(fā)生。

  筆者認(rèn)為由于應(yīng)用程序開發(fā)與數(shù)據(jù)庫設(shè)計(jì)是處于兩個不同的領(lǐng)域。故數(shù)據(jù)庫管理員需要跟應(yīng)用程序開發(fā)者進(jìn)行有效溝通。只有在雙方共同努力下,才能夠在最大限度內(nèi)避免這種情況的發(fā)生。

熱詞搜索:

上一篇:讓SQL Server的移動變得簡單
下一篇:如何選擇合適的備份技術(shù)

分享到: 收藏