鎖機制用於管理對共用資源的並發訪問。
在 Oracle 中,事務應該延遲到適當的時刻提交,因為事務很長或很大,一般不會對系統有壓力;行級鎖沒有相關的開銷,1個行鎖還是1000000個行鎖專用於鎖定這個資訊的“資源”數都是一樣的;
不要以為鎖定擴大“對系統更好”(例如使用表鎖而不是行鎖),oracle 中鎖定擴大對系統沒有任何好處,不會節省任何資源;可以同時得到並發性和一致性,資料讀取器不會被寫入器阻塞。
使用 ORA_ROWSCN 的樂觀鎖定:
ORA_ROWSCN 建立在內部 oracle 系統時鐘(SCN)基礎上。在 oracle 中,每次提交時,SCN 都會推進。除非建立表時支援在行級維護 ORA_ROWSCN ,否則 oracle 會在塊級維護。
建立表時啟用 ROWDEPENDENCIES,也可以使用 DBMS_REDEFINITION 中的線上重建功能。
查詢語句:select id, dbms_rowid.rowid_block_number(rowid) blockno, ora_rowscn from table
執行 INSERT、UPDATE、DELETE、MERGE 和 SELECT FOR UPDATE 時會阻塞,最後一個增加 NOWAIT 就不會阻塞。
oracle 從來不會鎖定擴大,但它會執行鎖轉換或鎖提升。主要有三類鎖:
1、DML 鎖:用於確保一次只有一個人能修改某一行,而且你正在處理一個表時別人不能刪除這個表。
a、TX鎖(事務鎖):事務發起第一個修改時會得到TX鎖,而且會一直持有這個鎖,直至事務執行提交或復原。
oralce 並沒有一個傳統的鎖管理器,不會用鎖管理器為系統中鎖定的每一行維護一個長長的列表。它只是簡單找到想鎖定的那一行並鎖定它。
在待鎖定的行所在的資料區塊的最前面有一個“開銷”空間,這裡會存放該塊的一個事務表,大小由建立對象時 CREATE 語句的兩個參數決定:
INITTRANS:初始的預分配大小,對於索引和表,預設為2。在頻繁修改的表上增加該值,同時 PCTFREE 值也需要相應的增加。
MAXTRANS:可以擴充到的最大值,預設為 255,即該塊最大的並發事務數。oracle 10g 該參數已經不再使用。
b、TM 鎖:用於確保在修改表的內容時,表的結構不會改變。
每個事務只能得到一個 TX 鎖,但修改多少個對象,就能得到多少個 TM 鎖。並且鎖的總數可以通過 DML_LOCKS 參數定義。
如果參數設定為 0,則不允許 DDL。通過 ALTER TABLE TABLENAME DISABLE TABLE LOCK 命令,逐個禁用 TM 鎖。
2、DDL 鎖:在 DDL 操作中會自動為對象加 DDL 鎖,從而保護這些對象不會被其他會話所修改。
a、獨佔鎖定:防止其它會話得到它們自己的 DDL 鎖或 TM 鎖。這說明 DDL 操作期間可以查詢表,但無法修改。
大多數 DDL 都帶有一個排他 DDL 鎖。例如 alter table t add new_column date;
例外:create index t_idx on t(x) online,它只會試圖得到表上的一個低級(mode 2)TM鎖,所以在 DDL 語句執行期間對錶所做的修改維護一個記錄,執行 CREATE 時再把這些修改應用至新的索引。
b、共用鎖定:保護所引用對象的結構,使之不會其他會話修改,但是允許修改資料。在建立儲存的編譯對象(如過程或視圖)時,會對依賴的對象加這種共用 DDL 鎖。
c、可中斷解析鎖:允許一個對象向另外某個對象註冊其依賴性。當某會話解析一條語句時,對該語句引用的每一個對象都會加一個解析鎖。目的是如果引用對象被修改,則將緩衝的語句置為無效。
利用視圖 DBA_DLL_LOCKS 查看該資訊。視圖指令碼:[ORACLE_HOME]/RDBMS/ADMIN\/catblock.sql
3、內部鎖和閂:閂是輕量級的序列化裝置,用於協調對共用資料結構、對象和檔案的多使用者訪問。設計為只保持極短的一段時間。使用諸如“測試和設定”以及“比較及交換”之類的原子指令來處理閂。
由於設定和釋放閂的指令是原子性的,儘管可能有多個進程在同時請求它,但作業系統本身可以保證只有一個進程能測試和設定閂。