隨筆-19  評(píng)論-5  文章-3  trackbacks-0
          在聯(lián)機(jī)事務(wù)處理(OLTP)的數(shù)據(jù)庫(kù)應(yīng)用系統(tǒng)中,多用戶、多任務(wù)的并發(fā)性是系統(tǒng)最重要的技術(shù)指標(biāo)之一。為了提高并發(fā)性,目前大部分RDBMS都采用加鎖技術(shù)。然而由于現(xiàn)實(shí)環(huán)境的復(fù)雜性,使用加鎖技術(shù)又不可避免地產(chǎn)生了死鎖問(wèn)題。因此如何合理有效地使用加鎖技術(shù),最小化死鎖是開發(fā)聯(lián)機(jī)事務(wù)處理系統(tǒng)的關(guān)鍵。          
          死鎖產(chǎn)生的原因           
              在聯(lián)機(jī)事務(wù)處理系統(tǒng)中,造成死機(jī)主要有兩方面原因。一方面,由于多用戶、多任務(wù)的并發(fā)性和事務(wù)的完整性要求,當(dāng)多個(gè)事務(wù)處理對(duì)多個(gè)資源同時(shí)訪問(wèn)時(shí),若雙方已鎖定一部分資源但也都需要對(duì)方已鎖定的資源時(shí),無(wú)法在有限的時(shí)間內(nèi)完全獲得所需的資源,就會(huì)處于無(wú)限的等待狀態(tài),從而造成其對(duì)資源需求的死鎖。           
              另一方面,數(shù)據(jù)庫(kù)本身加鎖機(jī)制的實(shí)現(xiàn)方法不同,各數(shù)據(jù)庫(kù)系統(tǒng)也會(huì)產(chǎn)生其特殊的死鎖情況。如在Sybase       SQL Server 11中,最小鎖為2K一頁(yè)的加鎖方法,而非行級(jí)鎖。如果某張表的記錄數(shù)少且記錄的長(zhǎng)度較短(即記錄密度高,如應(yīng)用系統(tǒng)中的系統(tǒng)配置表或系統(tǒng)參數(shù)表就屬于此類表),被訪問(wèn)的頻率高,就容易在該頁(yè)上產(chǎn)生死鎖。
                   
          容易發(fā)生死鎖的幾種情況如下:           
          1>不同的存儲(chǔ)過(guò)程、觸發(fā)器、動(dòng)態(tài)SQL語(yǔ)句段按照不同的順序同時(shí)訪問(wèn)多張表;              
          2>在交換期間添加記錄頻繁的表,但在該表上使用了非群集索引(non-clustered);              
          3>表中的記錄少,且單條記錄較短,被訪問(wèn)的頻率較高;          
          4>整張表被訪問(wèn)的頻率高(如代碼對(duì)照表的查詢等)。           

          以上死鎖情況的對(duì)應(yīng)處理方法如下: 
                 
          1>在系統(tǒng)實(shí)現(xiàn)時(shí)應(yīng)規(guī)定所有存儲(chǔ)過(guò)程、觸發(fā)器、動(dòng)態(tài)SQL語(yǔ)句段中,對(duì)多張表的操作總是使用同一順序。如:有兩個(gè)存儲(chǔ)過(guò)程proc1、proc2,都需要訪問(wèn)三張表zltab、z2tab和z3tab,如果proc1按照zltab、z2tab和z3tab的順序進(jìn)行訪問(wèn),那么,proc2也應(yīng)該按照以上順序訪問(wèn)這三張表。          
          2>對(duì)在交換期間添加記錄頻繁的表,使用群集索引(clustered),以減少多個(gè)用戶添加記錄到該表的最后一頁(yè)上,在表尾產(chǎn)生熱點(diǎn),造成死鎖。這類表多為往來(lái)賬的流水表,其特點(diǎn)是在交換期間需要在表尾追加大量的記錄,并且對(duì)已添加的記錄不做或較少做刪除操作。          
          3>對(duì)單張表中記錄數(shù)不太多,且在交換期間select或updata較頻繁的表可使用設(shè)置每頁(yè)最大行的辦法,減少數(shù)據(jù)在表中存放的密度,模擬行級(jí)鎖,減少在該表上死鎖情況的發(fā)生。這類表多為信息繁雜且記錄條數(shù)少的表。
                     
          如:系統(tǒng)配置表或系統(tǒng)參數(shù)表。在定義該表時(shí)添加如下語(yǔ)句:           
          with   max_rows_per_page=1           
          在存儲(chǔ)過(guò)程、觸發(fā)器、動(dòng)態(tài)SQL語(yǔ)句段中,若對(duì)某些整張表select操作較頻繁,則可能在該表上與其他訪問(wèn)該表的用戶產(chǎn)生死鎖。對(duì)于檢查賬號(hào)是否存在,但被檢查的字段在檢查期間不會(huì)被更新等非關(guān)鍵語(yǔ)句,可以采用在select命令中使用at       isolation       read       uncommitted子句的方法解決。該方法實(shí)際上降低了select語(yǔ)句對(duì)整張表的鎖級(jí)別,提高了其他用戶對(duì)該表操作的并發(fā)性。在系統(tǒng)高負(fù)荷運(yùn)行時(shí),該方法的效果尤為顯著。           
          如:          
          select * from titles at isolation read uncommitted          
          對(duì)流水號(hào)一類的順序數(shù)生成器字段,可以先執(zhí)行updata流水號(hào)字段+1,然后再執(zhí)行select獲取流水號(hào)的方法進(jìn)行操作。

          版權(quán)歸原作者和各發(fā)布網(wǎng)站所有,此文章僅供學(xué)習(xí)參考之用  

          天天學(xué)習(xí),好好向上——

          posted on 2008-11-06 18:11 東頭bing阿頭 閱讀(12376) 評(píng)論(0)  編輯  收藏 所屬分類: DataBase



          主站蜘蛛池模板: 泊头市| 明星| 南岸区| 正蓝旗| 仁化县| 黄平县| 香港 | 千阳县| 沁水县| 蓬溪县| 临夏县| 竹山县| 开江县| 武山县| 会宁县| 波密县| 永仁县| 鄂州市| 平湖市| 磐安县| 宝坻区| 琼结县| 明溪县| 晋州市| 大竹县| 商都县| 三都| 镇雄县| 陈巴尔虎旗| 阿鲁科尔沁旗| 昌宁县| 绥中县| 濮阳市| 离岛区| 邓州市| 大厂| 岳普湖县| 原平市| 玉田县| 高碑店市| 垣曲县|