死鎖產(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í),好好向上——