程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle教程 >> Oracle鎖1:DML鎖

Oracle鎖1:DML鎖

編輯:Oracle教程

Oracle鎖1:DML鎖


DML鎖,也叫做數據鎖(data lock),用於保證在多用戶操作數據時數據的完整。DML鎖防止相互沖突的DML和DDL操作同時發生。

DML鎖有行鎖(Row Locks,TX)和表鎖(Table Locks,TM),不同的DML操作會自動請求對應的鎖。

行鎖(Row Locks,TX)

行鎖也叫TX鎖,用於鎖表的一行數據。當一個事務對一行數據做INSERT、UPDATE、DELETE、MERGE或SELECT ... FOR UPDATE操作時,數據將為行添加行鎖,直到事務執行了commit或roll back操作後,行鎖才釋放。
行鎖防止兩個事務修改同一行數據,當一個事務修改一行數據時,數據庫總是為修改的行加一個排它鎖以至於其它事務無法修改該行,只有當事務執行了commit或者roll back操作後,數據庫才會釋放對應的鎖。行鎖是小粒度的鎖,為應用提供了最大限度的並行修改數據的能力。
當一個事務獲取了一個行鎖,那麼這個事務也需要獲取這行數據所在表的表鎖,表鎖阻止有沖突的DDL操作,即數據庫會自動的為更新的行添加一個排它鎖,並為行所在的表添加一個子排它鎖。

行鎖和並發

下面通過一個例子來理解行鎖和並發的關系。
首先創建下面的表格,並初始化數據:
create table employees(employee_id number(10),salary number(10));
insert into employees(employee_id,salary) values(100,512);
insert into employees(employee_id,salary) values(101,600);
......
步驟一:三個Session同時查詢ID為100和101的雇員,查詢結果一致
Session 1:
SELECT employee_id, salary FROM employees WHERE employee_id IN (100, 101);
EMPLOYEE_ID		SALARY
-------------------------
100				512
101				600

Session 2:
SELECT employee_id, salary FROM employees WHERE employee_id IN (100, 101);
EMPLOYEE_ID		SALARY
-------------------------
100				512
101				600

Session 3:
SELECT employee_id, salary FROM employees WHERE employee_id IN (100, 101);
EMPLOYEE_ID		SALARY
-------------------------
100				512
101				600
步驟二:Session 1執行更新操作,更新id為100的雇員,在這個更新中,寫者將請求一個行鎖,阻止其它寫者更新這行數據,如果其它寫者更新該行數據將被阻塞,直到Session 1提交或者回滾數據
Session 1:
update employees set salary = 612 where employee_id = 100
步驟三:再次執行步驟一的操作
Session 1:
SELECT employee_id, salary FROM employees WHERE employee_id IN (100, 101);
EMPLOYEE_ID		SALARY
-------------------------
100				612
101				600

Session 2:
SELECT employee_id, salary FROM employees WHERE employee_id IN (100, 101);
EMPLOYEE_ID		SALARY
-------------------------
100				512
101				600

Session 3:
SELECT employee_id, salary FROM employees WHERE employee_id IN (100, 101);
EMPLOYEE_ID		SALARY
-------------------------
100				512
101				600
Session 1的結果是它更新後的數據,而其他兩個session任然是舊數據。
步驟四:Session 2更新101雇員的薪水,並且不提交數據,這樣Session 2獲取了對雇員101的行鎖
UPDATE hr.employees SET salary = salary + 100 WHERE employee_id = 101;
步驟五:再次執行步驟1的查詢
Session 1:
SELECT employee_id, salary FROM employees WHERE employee_id IN (100, 101);
EMPLOYEE_ID		SALARY
-------------------------
100				612
101				600

Session 2:
SELECT employee_id, salary FROM employees WHERE employee_id IN (100, 101);
EMPLOYEE_ID		SALARY
-------------------------
100				512
101				700

Session 3:
SELECT employee_id, salary FROM employees WHERE employee_id IN (100, 101);
EMPLOYEE_ID		SALARY
-------------------------
100				512
101				600

行鎖的存儲

Oracle將鎖信息存儲在data block中。數據庫用一個隊列機制處理行鎖請求,如果一個事務請求一個未鎖定的行,那麼事務將放一個鎖到data block,被事務修改的每一行都指向存儲在block header中的事務ID的一個拷貝。
當一個事務結束時,事務ID保留在block header中,如果另一個事務想修改一行數據,那麼它用這個事務ID判定這個鎖是否是激活的。如果鎖是激活的,那麼當鎖被釋放時,該事務的session將被通知,否則,事務獲取這個鎖。

表鎖(Table Locks,TM)

表鎖,也叫TM鎖,當對表執行以下操作時將被請求:INSERT、UPDATE、DELETE、MERGE、SELECT ... FOR UPDATE和LOCK TABLE。請求表鎖的DML操作將阻止其它沖突的DDL操作。
表鎖有以下的模式:

Row Share(RS)

該鎖也叫subshare table lock(SS),表示事務持有表上的鎖已鎖定表中的行,並打算對其進行更新。Row share鎖是最小限制的表鎖,為表的行數據的高並發修改提供了支持。

Row Exclusive Table Lock(RX)

該所也叫subexclusive table lock(SX),通常表示持有鎖的事務更新了表的行或者執行了SELECT ... FOR UPDATE。SX鎖允許其它事務查詢、插入、更新、刪除或者在同一個表上鎖定多行數據,因此,SX鎖允許多個事務在同一個表上同時獲取SX和RS鎖。

Share Table Lock(S)

一個事務持有了表的S鎖,任然允許其他事務查詢該表格(除了用SELECT ... FOR UPDATE),但只有持有了S鎖的事務被允許更新表格。由於多個事務可以同時持有S鎖,獲取S鎖並不能保證事務能夠修改表格。

Share Row Exclusive Table Lock(SRX)

該鎖也叫share-subexclusive table lock(SSX),比S鎖限制更強。在一個表上一個時間點只能有一個事務能獲取SSX鎖。SSX鎖允許其它事務查詢表(除了用SELECT ... FOR UPDATE),但是不能更新表。

Exclusive Table Lock(X)

這個鎖限制最強,禁止其它事務執行任何類型的DML操作或對表防止任何鎖。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved