oracle中的鎖機制

polalisi發表於2008-07-10

鎖是一種機制,是用來管理對一個共享資源的並行訪問。
解停? 只有對資源進行並行訪問時才會用到鎖,但單個戶模式下的資料庫是不需要鎖的。所以鎖的目的就是在多個使用者並行訪問資料庫時為了保證資料的一致和準確性採用的一種保護機制。幾乎所有的資料庫都採用了鎖的機制,但其實現機制卻有很大的卻別。Oracle在鎖的處理上較SYBASE和informix有著明顯的優勢,特別是在行級鎖的處理上,基本上算是完美。

封鎖問題:
一個典型的程式設計缺陷例子。
A:使用者1檢索到一行資料,並準備修改。
B:使用者2檢索到相同的資料。
C:使用者2刪除了這一行,並提交。
D:使用者修改那一行,並提交,結果程式報錯,該行不存在。
使用者抱怨開發商,開發商認為是使用者人為因素造成。

分析:
當使用者1透過程式從資料庫中提取出自己想要修改的記錄時,該記錄並沒有鎖定,此時使用者2用同樣的條件檢索到該行,並刪除,提交導致該行不復存在,此時使用者1對檢索到的行修改後提交時,由於該行已經被刪除,導致使用者操作失敗。從而對軟體失去信心。
解決方法:
在對該行進行修改之前,對該行鎖定,防止其他人對該行進行dml操作。select * from tab for update nowait;
此時資料庫將在該行上建立一個行級排它鎖,直到等到一個commit或者rollback時才釋放。

一、悲觀封鎖
鎖在使用者修改之前就發揮作用:
Select ..for update(nowait)
Select * from tab1 for update
使用者發出這條命令之後,oracle將會對返回集中的資料建立行級封鎖,以防止其他使用者的修改。
如果此時其他使用者對上面返回結果集的資料進行dml或ddl操作都會返回一個錯誤資訊或發生阻塞。
1:對返回結果集進行update或delete操作會發生阻塞。
2:對該表進行ddl操作將會報:Ora-00054:resource busy and acquire with nowait specified.

原因分析
此時Oracle已經對返回的結果集上加了排它的行級鎖,所有其他對這些資料進行的修改或刪除操作都必須等待這個鎖的釋放,產生的外在現象就是其他的操作將發生阻塞,這個這個操作commit或rollback.
同樣這個查詢的事務將會對該表加表級鎖,不允許對該表的任何ddl操作,否則將會報出ora-00054錯誤::resource busy and acquire with nowait specified.

二、樂觀封鎖
樂觀的認為資料在select出來到update進取並提交的這段時間資料不會被更改。這裡面有一種潛在的危險就是由於被選出的結果集並沒有被鎖定,是存在一種可能被其他使用者更改的可能。因此Oracle仍然建議是用悲觀封鎖,因為這樣會更安全。

阻塞

定義:
當一個會話保持另一個會話正在請求的資源上的鎖定時,就會發生阻塞。被阻塞的會話將一直掛起,直到持有鎖的會話放棄鎖定的資源為止。4個常見的dml語句會產生阻塞
INSERT
UPDATE
DELETE
SELECT…FOR UPDATE


INSERT

Insert發生阻塞的唯一情況就是使用者擁有一個建有主鍵約束的表。當2個的會話同時試圖向表中插入相同的資料時,其中的一個會話將被阻塞,直到另外一個會話提交或會滾。一個會話提交時,另一個會話將收到主鍵重複的錯誤。回滾時,被阻塞的會話將繼續執行。

UPDATE 和DELETE當執行Update和delete操作的資料行已經被另外的會話鎖定時,將會發生阻塞,直到另一個會話提交或會滾。

Select …for update

當一個使用者發出select..for update的錯作準備對返回的結果集進行修改時,如果結果集已經被另一個會話鎖定,就是發生阻塞。需要等另一個會話結束之後才可繼續執行。可以透過發出 select… for update nowait的語句來避免發生阻塞,如果資源已經被另一個會話鎖定,則會返回以下錯誤:Ora-00054:resource busy and acquire with nowait specified.

死鎖-deadlock

定義:當兩個使用者希望持有對方的資源時就會發生死鎖.
即兩個使用者互相等待對方釋放資源時,oracle認定為產生了死鎖,在這種情況下,將以犧牲一個使用者作為代價,另一個使用者繼續執行,犧牲的使用者的事務將回滾.
例子:
1:使用者1對A表進行Update,沒有提交。
2:使用者2對B表進行Update,沒有提交。
此時雙反不存在資源共享的問題。
3:如果使用者2此時對A表作update,則會發生阻塞,需要等到使用者一的事物結束。
4:如果此時使用者1又對B表作update,則產生死鎖。此時Oracle會選擇其中一個使用者進行會滾,使另一個使用者繼續執行操作。
起因:
Oracle的死鎖問題實際上很少見,如果發生,基本上都是不正確的程式設計造成的,經過調整後,基本上都會避免死鎖的發生。

鎖的分類


按封鎖的物件可以分成:
DML lock
DDL lock

DML LOCK
DML鎖是用來保護資料在被並行訪問時資料的安全和一致性,按照限制級別的高低依次可以分成以下幾種:
1:ROWLOCK(TX)
DML:insert,update,delete ,select …for update.
這些操作會在所操作的行上建立排它鎖,直到所在的事物提交或會滾才釋放。

2:table-lock(TM )
當一個事物在進行DML操作時,所在的事務會對所操作的表加表級鎖,以保證在這個事務過程中表不被改變。
表級鎖按照限制等級可以分成以下幾類:
3:RS
Row share table lock
以下的操作會產生RS lock
Select * from tab for update.
LOCK TABLE table IN ROW SHARE MODE;
RS不允許的操作
LOCK TABLE table IN EXCLUSIVE MODE;

4:RX
Row Exclusive Table Locks
以下的操作會產生RS lock
1:INSERT,UPDATE ,DELETE
2:LOCK TABLE table IN ROW EXCLUSIVE MODE;
RX不允許的操作
LOCK TABLE table IN SHARE MODE;
LOCK TABLE table IN SHARE EXCLUSIVE MODE;
LOCK TABLE table IN EXCLUSIVE MODE;

5:S
Share Table Locks
以下操作產生S lock.
LOCK TABLE table IN SHARE MODE;
S不允許的操作
LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE;
LOCK TABLE table IN EXCLUSIVE MODE;
LOCK TABLE table IN ROW EXCLUSIVE MODE;

SRX
Share Row Exclusive Table Locks
以下操作產生SRX LOCK
LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE;
SRX不允許的操作.
LOCK TABLE table IN SHARE MODE;
LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE;
LOCK TABLE table IN ROW EXCLUSIVE MODE;
LOCK TABLE table IN EXCLUSIVE MODE;
X
Exclusive Table Locks
一下操作產生X LOCK
LOCK TABLE table IN EXCLUSIVE MODE;
X不允許的操作
不允許所有的操作

[@more@]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10455649/viewspace-1007086/,如需轉載,請註明出處,否則將追究法律責任。

相關文章