oracle 鎖機制

winston_DBA發表於2015-04-18
1.oracle鎖機制主要用於管理對共享資源的併發訪問,同時保證資料完整性和一致性。(其中完整性的一個體現例子為外來鍵未加索引,修改父表會鎖定整個字表)
2.常見DML阻塞語句:INSERT/UPDATE/DELETE/MERGE/SELECT FOR UPDATE
3.鎖行為
     只有當行記錄正在被修改時,該記錄才會被鎖定;    
     當某行記錄正在被修改,會阻塞其他程式的寫操作;
     oracle的寫入不會阻塞讀(透過undo實現);
     oracle的讀取不會阻塞寫(select ... for update除外);
4.鎖分為共享鎖和排他鎖
     獲得資源排他鎖的事務,會阻止該資源被共享,即只有佔有排他鎖的事務可以對該資源有使用許可權;
     獲得資源共享鎖的事務,允許該資源被共享,但是會阻止想要以排它鎖佔有該資源的會話;
     例如,會話A需要修改表T中的一行記錄,則會話A會給該記錄上的排它鎖,獲取整張表的共享鎖。這樣,其他會話可以對A事務修改記錄以外的所有記錄進行操作。但是如果會話C想要修改表結構,即需要獲取表T的排他鎖,則此時是不允許的,原因為會話A持有表T的共享鎖。
     注意:上例中是會話之間的關係!因為如果在同一個會話中,執行DDL,會自動提交之前的update操作,釋放表T上的共享鎖。
5.鎖轉換和鎖升級
     oracle只有在必要的時候進行鎖轉換,從來不進行鎖升級。
     鎖轉換是在同樣的鎖定粒度大小下,將鎖的限制等級升級;鎖升級是在同樣的限制等級下,將鎖定的粒度加大。
     oracle從來不會進行鎖升級,因為鎖升級極大的增加了發生死鎖的可能性。例如,事務1和事務2都需要進行鎖升級,並且倆事務都是因為相同的資源而發生了等待,這樣造成了死鎖。
6.鎖的持續時間
     oracle在事務不再需要資源時,例如回滾或者提交,會自動釋放鎖。通常情況下,在整個事務期間內,事務都會持有事務相關的鎖。這些鎖阻止了髒讀、更新丟失和破壞性的DDL的發生。
     注意:對子表的全表鎖是發生在主表的語句級別,而不是事務級別。甚至使用DBMS_LOCK可以人為的釋放和分配鎖,甚至鎖可以跨事務。
     oracle事務在回滾或者提交時,會釋放事務內的鎖資源。
     當然,當事務回滾到某個檢查點,則檢查點之後所需要的鎖資源也會被釋放。但是,每個事務只有在不再等待之前的資源時,才可以獲取當前可用的資源。當前等待的事務只有在原始事務回滾或者提交時,才會停止等待。
7.鎖和死鎖
     oracle會自動檢測死鎖,並且在語句級進行死鎖的回滾。
     oracle的死鎖主要發生在明確的覆蓋了預設的鎖機制,雖然oracle並不會升級鎖,也不使用查詢鎖,但是使用了記錄級別(row-level)的鎖,所以死鎖還是會偶爾發生。
8.自動鎖
     oracle會代替事務自動的對資源進行鎖定,組織其他事務以排他鎖的形式來訪問相同資源。根據資源的不同和對資源所做的操作的不同,資料庫需要不同的鎖和不同的限制等級。
     oracle鎖分為以下類別
自動鎖類別 描述
DML鎖 用於保護資料,例如表鎖用於保護整張表,行鎖用於鎖定指定的行。
DDL鎖 保護方案物件的結構,例如表或檢視的資料字典定義。
system鎖 保護資料庫內部結構,例如資料檔案、latches、mutexes和內部鎖。
9.DML鎖
     DML鎖包括行鎖(TX)和表鎖(TM):
     TX鎖主要是由於DML操作(insert/delete/update/merge/select ... for update)語句引起的行鎖,行鎖是最小粒度的排他鎖,保證了併發性和吞吐量。
     行鎖(TX)和併發性:當不同會話對同一張表的不同記錄做修改,且均未提交,則每個會話只能看到自己會話內所做的修改,不能看到其他未提交會話所做的修改,這樣提高了事務的併發性。
     行鎖(TX)的儲存:oracle將鎖的資訊儲存在資料塊頭部(有些資料庫透過鎖管理器在記憶體中管理鎖);oracle資料庫透過佇列機制來分配行鎖資源,當一個事務需要鎖定一條未被鎖定的記錄,則該事務會在該記錄所在資料塊頭部放一個鎖(包含事務ID等相關資訊),這樣所有被該事務修改的資料記錄,都會指向資料塊頭部儲存的事務ID(transaction ID);當事務結束的時候,事務ID(transaction ID)仍然留在資料塊頭部,如果其他會話想要修改該資料塊的某條記錄,會根據裡面儲存的事務ID來判斷其想要修改的記錄是否被其他鎖給鎖定了,若想要修改的記錄被鎖定,則需要等待鎖定記錄的事務結束後,再進行事務的處理。若想要修改的記錄沒有被鎖定,則直接獲取該記錄的行鎖(TX)。
     表級鎖(TM)主要是由於在表級發生的insert/update/delete/merge/select...for update/lock table操作語句而產生的。DML操作需要表級鎖來代替事務預留對於表的DML操作,並且防止與事務衝突的DDL操作。
     表級鎖有以下模式:
     Row Share(RS):最低限制級別的表鎖,提供最高階別的併發性。
     Row Exclusive Table Lock(RX):允許多事務同時獲取SX鎖
     Share Table Lock(S):允許多事務同時持有S鎖,且允許多事務同時進行查詢(select ... for update除外)但是想要更新內容,前提為只有一個事務持有S鎖。
     Share Row Exclusive Table lock(SRX):在某個時間點只允許一個事務持有SRX鎖,允許其他事務來對錶進行查詢(select ... for update除外),但是不允許進行update更新。
     Exclusive Table lock(X):最高階別的限制,獲取X鎖後,不允許其他事務在該表上進行任何型別的DML操作。
     表級鎖和外來鍵:
     當對父表的鍵值(主鍵或唯一鍵)進行更新時,對於子表的鎖定行為取決於自表的外來鍵是否建了索引:
     第一、如果子表外來鍵沒有建索引,則子表會頻繁的被鎖定,更容易發生死鎖。所以存在外來鍵的表必須在外來鍵上建索引,除非父表中的鍵值永遠也不會發生更新。 注意:子表中的DML操作不會對父表產生鎖定。
     第二、如果子表外來鍵建了索引,則對父表中對應鍵值的修改不會要求對子表進行鎖定。
10.DDL(data dictionary lock)鎖
     當使用DDL進行方案物件的定義進行操作時,DDL鎖會對語句中涉及到的物件進行鎖定,需要注意的是,oracle絕對不會對整個資料字典進行鎖定!
     當DDL語句執行時,oracle會自動的替DDL事務分配資料字典鎖。使用者不能夠顯式的申請資料字典鎖。例如,當使用者建立一個儲存過程,則建立儲存過程中涉及到的方案物件的資料字典資訊都會被鎖定,防止被破壞,直到儲存過程結束後,釋放相應資料字典鎖。
     排他資料字典鎖:該鎖會阻止其他會話獲得DDL或者DML鎖。也就是說,在有事務持有DDL鎖時,無法對錶結構定義進行修改,也無法對錶中的資料進行修改,只允許查詢。
     共享資料字典鎖:該鎖允許多事務同時持有,但是持有的事務不能夠對相關聯的方案物件定義進行修改。但是允許對資料內容進行修改。
     可中斷解析鎖:這些鎖允許一個物件向另外某個物件註冊其依賴性。
11.系統鎖
     閂:閂是一種低階的序列化裝置,用於協調對共享資料結構、物件和檔案的多使用者訪問。主要用於保護一下場景中的資料結構:
     1.多個會話的併發修改;
     2.當一個會話在修改某資料結構時,允許另一會話進行讀取;
     3.當處理資料結構時,進行記憶體回收。
     一般來說,一個閂會對SGA中的多個物件進行保護。
     互斥鎖:互斥鎖是一種防止物件在多程式併發訪問的時候從記憶體中老化或者被破壞的一種低階機制。
     互斥鎖的好處:互斥鎖有可能減輕競爭壓力;互斥鎖比閂消耗更少的記憶體;在共享模式,互斥鎖允許多會話的併發。
12.內部鎖
     內部鎖是高階的、複雜的且服務於多種目的的一種鎖機制。
     oracle內部鎖主要包括:資料字典快取鎖、檔案和日誌管理鎖和表空間和undo段鎖
13.人工鎖
     人工鎖主要應用場景:應用要求事務級別的讀一致性或者可重複讀;應用要求事務以排他形式來訪問資源,這樣事務就不需要等待其他事務完成。
     oracle支援手工修改系統預設自動鎖:
     在會話級別,可以透過alter session來修改;
     在事務級別,可以透過set transaction isolation level語句;lock table/view語句;select ... for update 三條語句來修改。
     使用者自定義鎖:透過DBMS_LOCK包來實現。


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

相關文章