INFORMIX使用鎖技術(shù)解決在多用戶訪問(wèn)數(shù)據(jù)庫(kù)情況下,對(duì)同一對(duì)象訪問(wèn)的并發(fā)控制問(wèn)題。INFORMIX支持復(fù)雜的、可伸縮性的鎖技術(shù)。
鎖的類(lèi)型
INFORMIX有三種不同類(lèi)型的鎖。它們?cè)诓煌那闆r下使用。
1. SHARED鎖
SHARED鎖只保留對(duì)象的可讀性。當(dāng)鎖存在時(shí),對(duì)象不能改變。多個(gè)程序可對(duì)同個(gè)對(duì)象加SHARED鎖。
2. EXCLUSIVE鎖
只能使單個(gè)程序使用。在程序要改變對(duì)象時(shí)使用。當(dāng)其他鎖存在時(shí),EXCLUSIVE鎖不能使用。當(dāng)使用了EXCLUSIVE 鎖后,其他鎖不能用于同一對(duì)象。
3. PROMOTABLE鎖
實(shí)現(xiàn)更新的目的。PROMOTABLE鎖可以放在已經(jīng)有SHARED鎖的記錄,但不能放在已經(jīng)有PROMOTABLE鎖和EXCLUSIVE鎖的地方。當(dāng)記錄上無(wú)其他鎖(含SHARED 鎖)情況下,這時(shí)在程序準(zhǔn)備改變鎖的記錄時(shí),PROMOTABLE鎖可以提升為EXCLUSIVE鎖。如果在已有SHARED鎖的記錄上設(shè)置了PROMOTABLE鎖,在PROMOTABLE鎖可以提升到EXCLUSIVE鎖之前需要?jiǎng)h除SHARED 鎖。PROMOTABLE鎖只能在INFORMIX Universal Server中支持。
鎖的范圍
INFORMIX對(duì)于數(shù)據(jù)鎖定提供了三種不同的方式,范圍由大到小分別是數(shù)據(jù)庫(kù)、表、記錄級(jí)鎖。使用的時(shí)機(jī)要看應(yīng)
用狀況而定。
1. 數(shù)據(jù)庫(kù)級(jí)鎖
你可以用CONNECT, DATABASE, 或 CREATE DATABASE語(yǔ)句打開(kāi)數(shù)據(jù)庫(kù)。打開(kāi)數(shù)據(jù)庫(kù)的操作就在數(shù)據(jù)庫(kù)上設(shè)置了SHARED鎖。只要程序打開(kāi)一個(gè)數(shù)據(jù)庫(kù),SHARED鎖就會(huì)阻止其他程序刪除數(shù)據(jù)庫(kù)或在數(shù)據(jù)庫(kù)上設(shè)置EXCLUSIVE鎖。你可以用語(yǔ)句DATABASE database name EXCLUSIVE鎖定整個(gè)數(shù)據(jù)庫(kù)。若此時(shí)其他用戶正在使用該數(shù)據(jù)庫(kù),該操作將返回錯(cuò)誤。一旦設(shè)置了EXCLUSIVE鎖,其他程序就不能打開(kāi)數(shù)據(jù)庫(kù),因?yàn)榇蜷_(kāi)時(shí)要放置一個(gè)SHARED鎖。只有數(shù)據(jù)庫(kù)關(guān)閉時(shí),數(shù)據(jù)庫(kù)鎖才釋放。你可以用DISCONNECT或CLOSE DATABASE顯示地處理,也可以運(yùn)行其他的DATABASE語(yǔ)句隱含的處理。一般數(shù)據(jù)庫(kù)級(jí)EXCLUSIVE鎖是獨(dú)占數(shù)據(jù)庫(kù)資源,防止其他程序訪問(wèn)數(shù)據(jù)庫(kù)。它使得程序非常簡(jiǎn)單,不會(huì)產(chǎn)生并發(fā)效果。常用在非高峰時(shí)期要改變大量數(shù)據(jù)時(shí)如數(shù)據(jù)庫(kù)備份過(guò)程。
2. 表級(jí)鎖
INFORMIX提供兩種模式表級(jí)鎖:EXCLUSIVE MODE 和SHARE MODE。你可以鎖整個(gè)表。在某些情況下,這個(gè)操作是自動(dòng)進(jìn)行。當(dāng)INFORMIX處理下列語(yǔ)句時(shí),一般鎖整個(gè)的表:ALTER INDEX 、ALTER TABLE 、CREATE INDEX、DROP INDEX 、RENAME COLUMN、RENAME TABLE 。該語(yǔ)句結(jié)束或事務(wù)結(jié)束會(huì)釋放該鎖。在某些查詢語(yǔ)句中,INFORMIX也自動(dòng)鎖整個(gè)表。你可以用LOCK TABLE語(yǔ)句顯示地鎖整個(gè)表。該語(yǔ)句允許你對(duì)整個(gè)表設(shè)置EXCLUSIVE鎖或SHARED鎖。當(dāng)你程序從表中讀取數(shù)據(jù)時(shí),SHARED鎖防止表中數(shù)據(jù)更新。INFORMIX Universal Server 通過(guò)設(shè)置隔離級(jí)別實(shí)現(xiàn)更大程度并發(fā)數(shù)據(jù)保護(hù)。
表級(jí)EXCLUSIVE鎖防止對(duì)同個(gè)表的并發(fā)使用。因此,如果其他許多程序要使用該表時(shí),系統(tǒng)性能會(huì)受到嚴(yán)重影響。類(lèi)似數(shù)據(jù)庫(kù)級(jí)EXCLUSIVE鎖,表級(jí)EXCLUSIVE鎖常用在非高峰時(shí)期要改變大量數(shù)據(jù)時(shí)。例如,有些應(yīng)用在高峰期間并不更新表,它們可以在非高峰期間定期以批處理方式更新。
通過(guò)UNLOCK TABLE table name 解除鎖。當(dāng)存在事務(wù)時(shí),事務(wù)結(jié)束時(shí)解除鎖。
3. 記錄級(jí)、頁(yè)級(jí)、鍵字級(jí)鎖
表的一個(gè)記錄是可設(shè)置鎖的最小對(duì)象。一個(gè)程序可以鎖一個(gè)記錄或記錄的集合,同時(shí)其他程序可以操作同一個(gè)表的其他記錄。Universal Server 以磁盤(pán)頁(yè)面(disk pages)為單位存儲(chǔ)數(shù)據(jù)。一個(gè)磁盤(pán)頁(yè)面包含一個(gè)或多個(gè)記錄。在有些情況下,頁(yè)級(jí)鎖比單個(gè)鎖更好些。其他數(shù)據(jù)庫(kù)服務(wù)器可能不存在頁(yè)級(jí)、鍵字級(jí)鎖。
在Universal Server上,當(dāng)你創(chuàng)建表時(shí),你可以選擇使用記錄級(jí)鎖或頁(yè)級(jí)鎖。其他的數(shù)據(jù)庫(kù)服務(wù)器不提供這種選擇。頁(yè)級(jí)、記錄級(jí)鎖有相同的效果。當(dāng)Universal Server需要鎖一個(gè)記錄時(shí),根據(jù)表創(chuàng)建時(shí)的鎖模式,鎖這個(gè)記錄或記錄所在的頁(yè)面。在一定情況下,數(shù)據(jù)庫(kù)服務(wù)器需要鎖一個(gè)不存在的記錄。它的效果相當(dāng)于在記錄將要存在的地方放一個(gè)
鎖。當(dāng)表使用記錄鎖時(shí),對(duì)假想的記錄使用鍵字鎖。當(dāng)表使用頁(yè)級(jí)鎖時(shí),含有或可能含有鍵字的索引頁(yè)將被設(shè)置鍵級(jí)鎖。
鎖的時(shí)期
程序控制數(shù)據(jù)庫(kù)級(jí)鎖的時(shí)期。數(shù)據(jù)庫(kù)關(guān)閉時(shí),數(shù)據(jù)庫(kù)鎖級(jí)也就釋放。表級(jí)、記錄級(jí)、索引級(jí)鎖的時(shí)期依賴(lài)于使用的SQL語(yǔ)句以及是否使用事務(wù)。如果數(shù)據(jù)庫(kù)沒(méi)有使用事務(wù),也就是說(shuō),事務(wù)日志不存在并且你沒(méi)有使用COMMIT WORK語(yǔ)句,當(dāng)運(yùn)行UNLOCK TABLE語(yǔ)句時(shí),表級(jí)鎖就釋放。當(dāng)使用了事務(wù)時(shí),事務(wù)結(jié)束,表級(jí)、記錄級(jí)、索引級(jí)鎖都釋放。
修改時(shí)鎖的處理
當(dāng)數(shù)據(jù)庫(kù)服務(wù)器通過(guò)一個(gè)更新游標(biāo)取一條記錄時(shí),它在該記錄上設(shè)置一個(gè)PROMOTABLE鎖。如果這個(gè)動(dòng)作成功,數(shù)據(jù)庫(kù)服務(wù)器知道其他程序不能改變此記錄。因?yàn)镻ROMOTABLE鎖不是獨(dú)占的,其他程序能夠繼續(xù)讀這條記錄。由于在取此記錄的程序執(zhí)行UPDATE、DELETE語(yǔ)句或簡(jiǎn)單地取下一條記錄之前,它可能花一些時(shí)間。這樣就提高了性能。當(dāng)它改變一個(gè)記錄時(shí),數(shù)據(jù)庫(kù)服務(wù)器在這條記錄上設(shè)置一個(gè)EXCLUSIVE鎖。如果它已經(jīng)有一個(gè)PROMOTABLE鎖,它將鎖改為EXCLUSIVE狀態(tài)。
EXCLUSIVE鎖的時(shí)期依賴(lài)于是否使用事務(wù)。如果沒(méi)有使用事務(wù),被修改的記錄寫(xiě)到磁盤(pán)上就會(huì)釋放該鎖。當(dāng)使用了事務(wù)時(shí),
鎖就會(huì)保持到事務(wù)的結(jié)束。這個(gè)動(dòng)作防止其他程序使用可能回滾到原來(lái)狀態(tài)的記錄。
當(dāng)使用了事務(wù)時(shí),只要?jiǎng)h除記錄鍵級(jí)鎖就會(huì)設(shè)置。使用鍵級(jí)鎖解決下列錯(cuò)誤:程序A刪除一個(gè)記錄,程序B插入有同樣鍵的記錄。程序A回滾事務(wù),使數(shù)據(jù)庫(kù)服務(wù)器恢復(fù)了刪除的記錄,這時(shí)程序B插入的記錄怎么辦?通過(guò)鎖索引,數(shù)據(jù)庫(kù)服務(wù)器等到程序A提交事務(wù)時(shí)才插入記錄。
由于 Universal Server數(shù)據(jù)庫(kù)服務(wù)器管理自己的鎖,所以它能提供不同類(lèi)型的鎖。其他的數(shù)據(jù)庫(kù)服務(wù)器是通過(guò)操作系統(tǒng)的特性實(shí)現(xiàn)鎖,所以不能提供多種選擇。有些操作系統(tǒng)通過(guò)操作系統(tǒng)服務(wù)方式向外提供鎖函數(shù)。在這些系統(tǒng),數(shù)據(jù)庫(kù)支持SET LOCK MODE語(yǔ)句。而有些操作系統(tǒng)不支持內(nèi)核級(jí)的特性,數(shù)據(jù)庫(kù)這時(shí)通過(guò)在數(shù)據(jù)庫(kù)目錄下產(chǎn)生小文件實(shí)現(xiàn)鎖。這些文件帶有.lok后綴。如果你的程序使用單個(gè)SELECT語(yǔ)句或沒(méi)有用FOR UPDATE聲明的游標(biāo)提取一個(gè)記錄,此記錄不管是否被一個(gè)未完成的交易上鎖會(huì)馬上被提取。這樣能產(chǎn)生最好的性能。當(dāng)你使用FOR UPDATE聲明的游標(biāo)時(shí),它在提取前將當(dāng)前記錄上鎖。如果當(dāng)前記錄已經(jīng)有鎖,隨作選擇模式的不同,程序會(huì)等待或返回錯(cuò)誤。當(dāng)取下一個(gè)記錄時(shí),數(shù)據(jù)庫(kù)看當(dāng)前記錄是否更新(使用帶WHERE CURRENT OF 的UPDATE)
鎖的模式
鎖的模式?jīng)Q定程序遇到被鎖的數(shù)據(jù)會(huì)產(chǎn)生怎樣的結(jié)果。當(dāng)程序要提取或修改一個(gè)上鎖的記錄時(shí),會(huì)有下面幾種情況:
1、 數(shù)據(jù)庫(kù)馬上通過(guò)SQLCODE變量或SQLSTATE結(jié)構(gòu)給程序返回一個(gè)錯(cuò)誤代碼。
2、 在數(shù)據(jù)解鎖前,數(shù)據(jù)庫(kù)將程序掛起。
3、數(shù)據(jù)庫(kù)將程序掛起一段時(shí)間。如果鎖還未解,數(shù)據(jù)庫(kù)給程序返回一個(gè)錯(cuò)誤代碼。
你可以通過(guò)SET LOCK MODE模式選擇以上結(jié)果。
如果你喜歡程序等待(對(duì)大多數(shù)程序而言這是最好的選擇),運(yùn)行下列語(yǔ)句:SET LOCK MODE TO WAIT。
當(dāng)設(shè)置了鎖模式后,程序常忽視其他并發(fā)程序的存在性。如果程序需要訪問(wèn)其他程序已上鎖的記錄時(shí),它等待別的程序解鎖,然后繼續(xù)。延遲的時(shí)間常不可預(yù)測(cè)。
等待解鎖不利的一面就是可能會(huì)等待很長(zhǎng)時(shí)間。如果不能接受很長(zhǎng)延遲,程序可以運(yùn)行下列語(yǔ)句:SET LOCK MODE TONOT WAIT選擇不等待。當(dāng)程序需要一個(gè)鎖記錄時(shí),它馬上返回一個(gè)錯(cuò)誤代碼,且當(dāng)前的SQL語(yǔ)句終止。這時(shí),程序必須回滾當(dāng)前的交易再試一次。程序開(kāi)始時(shí),數(shù)據(jù)庫(kù)初始設(shè)置為不等待。
當(dāng)你使用UNIVERSAL SERVER時(shí),你有另外的選擇。你可以讓數(shù)據(jù)庫(kù)設(shè)置等待時(shí)間的上限。你可用下列語(yǔ)句:SETLOCK MODE
TO WAIT 18讓數(shù)據(jù)庫(kù)有18秒等待上限。若期間鎖還沒(méi)有解開(kāi),將返回錯(cuò)誤代碼。
在每個(gè)程序都選擇了鎖等待模式情況下,有可能出現(xiàn)死鎖。死鎖是程序之間相互阻塞,每個(gè)程序在其他程序要訪問(wèn)的對(duì)象上設(shè)置了鎖。UNIVERSAL SERVER在單個(gè)網(wǎng)絡(luò)服務(wù)器情況下會(huì)馬上檢測(cè)到死鎖。如果程序選擇了鎖等待模式,通過(guò)給程序返回錯(cuò)誤代碼,你就知道你遇到了死鎖。而在多個(gè)數(shù)據(jù)庫(kù)服務(wù)器的情況下,UNIVERSAL SERVER不能馬上檢測(cè)到。每個(gè)數(shù)據(jù)庫(kù)服務(wù)器都設(shè)置鎖等待的上限。如果超時(shí),數(shù)據(jù)庫(kù)服務(wù)器就認(rèn)為發(fā)生了死鎖且返回相關(guān)的錯(cuò)誤代碼。數(shù)據(jù)庫(kù)管理員可以設(shè)置和修改等待時(shí)間的上限。
轉(zhuǎn)自:
http://blog.chinaunix.net/u/14063/showart.php?id=114859
posted on 2009-11-15 23:22
chatler 閱讀(374)
評(píng)論(0) 編輯 收藏 引用 所屬分類(lèi):
Database