亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > 綜合 > 正文

通過意向鎖多粒度封鎖機制進行并發控制

2024-07-21 02:42:35
字體:
來源:轉載
供稿:網友
1.數據庫鎖的概念

為了確保并發用戶在存取同一數據庫對象時的正確性(即無丟失修改、可重復讀、不讀

“臟”數據),數據庫中引入了鎖機制?;镜逆i類型有兩種:排它鎖(Exclusive locks 記

為X 鎖)和共享鎖(Share locks記為 S鎖)。

排它鎖:若事務T對數據D加X鎖,則其它任何事務都不能再對D加任何類型的鎖,

直至T 釋放D 上的X 鎖;一般要求在修改數據前要向該數據加排它鎖,所以排它鎖又稱為

寫鎖。

共享鎖:若事務T對數據D加S 鎖,則其它事務只能對D加 S鎖,而不能加X 鎖,直

至 T 釋放 D 上的 S 鎖;一般要求在讀取數據前要向該數據加共享鎖,所以共享鎖又稱為讀

鎖。

2.Oracle多粒度封鎖機制介紹

根據保護對象的不同,Oracle數據庫鎖可以分為以下幾大類:

(1) DML lock(data locks,數據鎖):用于保護數據的完整性;

(2) DDL lock(dictionary locks,字典鎖):用于保護數據庫對象的結構(例如表、視圖、索

引的結構定義);

(3) internal locks 和 l a t c h es(內部鎖與閂):保護內部數據庫結構;

(4) distributed locks(分布式鎖):用于OPS(并行服務器)中;

(5) PCM locks(并行高速緩存管理鎖):用于OPS(并行服務器)中。

本文主要討論DML(也可稱為data locks,數據鎖)鎖。從封鎖粒度(封鎖對象的大?。?

的角度看,Oracle DML鎖共有兩個層次,即行級鎖和表級鎖。

2.1 Oracle 的 TX 鎖(行級鎖、事務鎖)

許多對Oracle不太了解的技術人員可能會以為每一個 TX鎖代表一條被封鎖的數據行,

其實不然。 TX的本義是Transaction (事務),當一個事務第一次執行數據更改(Insert、 Update、

Delete)或使用SELECT… FOR UPDATE 語句進行查詢時,它即獲得一個TX(事務)鎖,

直至該事務結束(執行COMMIT 或ROLLBACK操作)時,該鎖才被釋放。所以,一個TX

鎖,可以對應多個被該事務鎖定的數據行。

在 Oracle 的每行數據上,都有一個標志位來表示該行數據是否被鎖定。Oracle 不象其

它一些 DBMS(數據庫管理系統)那樣,建立一個鏈表來維護每一行被加鎖的數據,這樣

就大大減小了行級鎖的維護開銷,也在很大程度上避免了其它數據庫系統使用行級封鎖時經

常發生的鎖數量不夠的情況。數據行上的鎖標志一旦被置位,就表明該行數據被加 X 鎖,

Oracle在數據行上沒有 S鎖。 2.2 TM鎖(表級鎖)

2.2.1 意向鎖的引出

表是由行組成的,當我們向某個表加鎖時,一方面需要檢查該鎖的申請是否與原有的表

級鎖相容;另一方面,還要檢查該鎖是否與表中的每一行上的鎖相容。比如一個事務要在一

個表上加 S 鎖,如果表中的一行已被另外的事務加了 X 鎖,那么該鎖的申請也應被阻塞。

如果表中的數據很多,逐行檢查鎖標志的開銷將很大,系統的性能將會受到影響。為了解決

這個問題,可以在表級引入新的鎖類型來表示其所屬行的加鎖情況,這就引出了“意向鎖”

的概念。

意向鎖的含義是如果對一個結點加意向鎖,則說明該結點的下層結點正在被加鎖;對任

一結點加鎖時,必須先對它的上層結點加意向鎖。如:對表中的任一行加鎖時,必須先對它

所在的表加意向鎖,然后再對該行加鎖。這樣一來,事務對表加鎖時,就不再需要檢查表中

每行記錄的鎖標志位了,系統效率得以大大提高。

2.2.2 意向鎖的類型

由兩種基本的鎖類型(S鎖、X 鎖),可以自然地派生出兩種意向鎖:

意向共享鎖(Intent Share Lock,簡稱 IS 鎖):如果要對一個數據庫對象加S鎖,首先

要對其上級結點加IS 鎖,表示它的后裔結點擬(意向)加 S鎖;

意向排它鎖(Intent Exclusive Lock,簡稱 IX 鎖):如果要對一個數據庫對象加X 鎖,

首先要對其上級結點加 IX鎖,表示它的后裔結點擬(意向)加X 鎖。

另外,基本的鎖類型(S、X)與意向鎖類型(IS、IX)之間還可以組合出新的鎖類型,

理論上可以組合出4種,即:S+IS,S+IX,X+IS,X+IX,但稍加分析不難看出,實際上只

有 S+IX 有新的意義,其它三種組合都沒有使鎖的強度得到提高(即:S+IS=S,X+IS=X,

X+IX=X,這里的“=”指鎖的強度相同)。所謂鎖的強度是指對其它鎖的排斥程度。

這樣我們又可以引入一種新的鎖的類型

共享意向排它鎖(Shared Intent Exclusive Lock,簡稱 SIX 鎖) :如果對一個數據庫對象

加 SIX 鎖,表示對它加 S 鎖,再加 IX 鎖,即 SIX=S+IX。例如:事務對某個表加 SIX 鎖,

則表示該事務要讀整個表(所以要對該表加S 鎖),同時會更新個別行(所以要對該表加 IX

鎖)。

這樣數據庫對象上所加的鎖類型就可能有5 種:即S、X、IS、IX、SIX。

具有意向鎖的多粒度封鎖方法中任意事務 T 要對一個數據庫對象加鎖,必須先對它的

上層結點加意向鎖。申請封鎖時應按自上而下的次序進行;釋放封鎖時則應按自下而上的次

序進行;具有意向鎖的多粒度封鎖方法提高了系統的并發度,減少了加鎖和解鎖的開銷。

2.2.3 Oracle 的 TM 鎖(表級鎖)

Oracle的 DML鎖(數據鎖)正是采用了上面提到的多粒度封鎖方法,其行級鎖雖然只

有一種(即X鎖),但其 TM鎖(表級鎖)類型共有5種,分別稱為共享鎖(S鎖)、排它鎖

(X 鎖)、行級共享鎖(RS 鎖)、行級排它鎖(RX 鎖)、共享行級排它鎖(SRX 鎖),與上面提到的S、X、IS、IX、SIX 相對應。需要注意的是,由于Oracle在行級只提供X鎖,所

以與RS鎖(通過SELECT … FOR UPDATE語句獲得)對應的行級鎖也是X鎖(但是該行

數據實際上還沒有被修改),這與理論上的IS 鎖是有區別的。

下表為Oracle數據庫TM鎖的相容矩陣(Y=Yes,表示相容的請求; N=No,表示不相

容的請求;-表示沒有加鎖請求):

T2

T1

S X RS RX SRX -

S Y N Y N N Y

X N N N N N Y

RS Y N Y Y Y Y

RX N N Y Y N Y

SRX N N Y N N Y

- Y Y Y Y Y Y

表一:Oracle 數據庫 TM 鎖的相容矩陣

一方面,當Oracle 執行SELECT…FOR UPDATE、 INSERT、 UPDATE、 DELETE等 DML

語句時,系統自動在所要操作的表上申請表級RS鎖(SELECT…FOR UPDATE)或 RX鎖

(INSERT、UPDATE、DELETE),當表級鎖獲得后,系統再自動申請 TX 鎖,并將實際鎖

定的數據行的鎖標志位置位(指向該TX鎖);另一方面,程序或操作人員也可以通過 LOCK

TABLE 語句來指定獲得某種類型的TM鎖。下表總結了 Oracle中各 SQL語句產生 TM鎖的

情況:

SQL語句 表鎖模式 允許的鎖模式

Select * from table_name…… 無 RS、RX、S、SRX、X

Insert into table_name…… RX RS、RX

Update table_name…… RX RS、RX

Delete from table_name…… RX RS、RX

Select * from table_name for update RS RS、RX、S、SRX

lock table table_name in row share mode RS RS、RX、S、SRX

lock table table_name in row exclusive mode RX RS、RX

lock table table_name in share mode S RS、S

lock table table_name in share row exclusive mode SRX RS

lock table table_name in exclusive mode X 無

表二:Oracle 數據庫 TM 鎖小結

我們可以看到,通常的 DML 操作(SELECT…FOR UPDATE、INSERT、UPDATE、

DELETE),在表級獲得的只是意向鎖(RS或 RX),其真正的封鎖粒度還是在行級;另外,

Oracle數據庫的一個顯著特點是,在缺省情況下,單純地讀數據(SELECT)并不加鎖, Oracle

通過回滾段(Rollback segment)來保證用戶不讀“臟”數據。這些都極大地提高了系統的

并發程度。

由于意向鎖及數據行上鎖標志位的引入,極大地減小了 Oracle 維護行級鎖的開銷,這

些技術的應用使Oracle 能夠高效地處理高度并發的事務請求。 3 Oracle 多粒度封鎖機制的監控

3.1 系統視圖介紹

為了監控Oracle系統中鎖的狀況,我們需要對幾個系統視圖有所了解:

3.1.1 v$lock視圖

v$lock視圖列出當前系統持有的或正在申請的所有鎖的情況,其主要字段說明如下:

字段名稱 類型 說明

SID NUMBER 會話(session)標識;

TYPE VARCHAR(2) 區分該鎖保護對象的類型;

ID1 NUMBER 鎖標識1;

ID2 NUMBER 鎖標識2;

LMODE NUMBER 鎖模式: 0 (None), 1 (null) ,2 (row share) , 3 (row exclusive) ,4

(share),5(share row exclusive),6(exclusive)

REQUEST NUMBER 申請的鎖模式:具體值同上面的LMODE

CTIME NUMBER 已持有或等待鎖的時間;

BLOCK NUMBER 是否阻塞其它鎖申請;

表三:v$lock 視圖主要字段說明

其中在TYPE 字段的取值中,本文只關心 TM、TX兩種DML鎖類型;

關于ID1、ID2,TYPE取值不同其含義也有所不同:

TYPE ID1 ID2

TM 被修改表的標識(object_id) 0

TX 以十進制數值表示該事務所占用的回滾段號與該事

務在該回滾段的事務表(Transaction table)中所占

用的槽號(slot number,可理解為記錄號)。其組成

形式為: 0xRRRrssSS ( RRRR = RBS number,

SSSS = slot )。

以十進制數值表示環繞

(wrap)次數,即該槽(slot)

被重用的次數;

表四:v$lock 視圖中 ID1與 ID2 字段取值說明

3.1.2 v$locked_object 視圖

v$locked_object視圖列出當前系統中哪些對象正被鎖定,其主要字段說明如下:

字段名稱 類型 說明

XIDUSN NUMBER 回滾段號;

XIDSLOT NUMBER 槽號;

XIDSQN NUMBER 序列號;

OBJECT_ID NUMBER 被鎖對象標識; SESSION_ID NUMBER 持有鎖的會話(SESSION)標識;

ORACLE_USERNAME VARCHAR2(30) 持有該鎖的用戶的Oracle用戶名;

OS_USER_NAME VARCHAR2(15) 持有該鎖的用戶的操作系統用戶名;

PROCESS VARCHAR2(9) 操作系統的進程號;

LOCKED_MODE NUMBER 鎖模式,取值同表三中的LMODE;

表五:v$locked_object 視圖字段說明

3.2 監控腳本

根據上述系統視圖,可以編制腳本來監控數據庫中鎖的狀況。

3.2.1 showlock.sql

第一個腳本 showlock.sql,該腳本通過連接 v$locked_object 與 all_objects 兩視圖,顯示

哪些對象被哪些會話鎖住:

/* showlock.sql */

column o_name format a10

column lock_type format a20

column object_name format a15

select rpad(oracle_username,10) o_name,session_id sid,

decode(locked_mode,0,'None',1,'Null',2,'Row share',

3,'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive') lock_type,

object_name ,xidusn,xidslot,xidsqn

from v$locked_object,all_objects

where v$locked_object.object_id=all_objects.object_id;

3.2.2 showalllock.sql

第二個腳本showalllock.sql,該腳本主要顯示當前所有 TM、TX鎖的信息;

/* showalllock.sql */

select sid,type,id1,id2,

decode(lmode,0,'None',1,'Null',2,'Row share',

3,'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive')

lock_type,request,ctime,block

from v$lock

where TYPE IN('TX','TM');

4.Oracle多粒度封鎖機制示例

以下示例均運行在Oracle 8.1.7上,數據庫版本不同,其輸出結果也可能有所不同。首

先建立3個會話,其中兩個(以下用 SESS#1、SESS#2 表示)以SCOTT用戶連入數據庫,以操作 Oracle 提供的示例表(DEPT、EMP);另一個(以下用 SESS#3 表示)以 SYS 用戶

連入數據庫,用于監控;

4.1 操作同一行數據引發的鎖阻塞

SESS#1:

SQL> select * from dept for update;

DEPTNO DNAME LOC

---------- -------------- -------------

10 account 70

20 research 8

30 sales 8

40 Operations 8

SESS#3:

SQL> @showlock

O_NAME SID LOCK_TYPE OBJECT_NAME XIDUSN XIDSLOT XIDSQN

---------- ----- --------------- --------------- ------ ------- ------

SCOTT 17 Row share DEPT 8 2 5861

SQL> @showalllock

SID TY ID1 ID2 LOCK_TYPE REQUEST CTIME BLOCK

----- -- ---------- ---------- --------------- ---------- ---------- ----------

17 TX 524290 5861 Exclusive 0 761 0

17 TM 32970 0 Row share 0 761 0

如第一個腳本showlock 所示,執行完SELECT…FOR UPDATE 語句后, SESS#1(SID

為 17)在 DEPT 表上獲得 Row share 鎖;如第二個腳本 showalllock 所示,SESS#1 獲得的

TX鎖為Exclusive,這些都驗證了上面的理論分析。另外,我們可以將TX鎖的 ID1按如下

方法進行分解:

SQL> select trunc(524290/65536) xidusn,mod(524290,65536) xidslot from dual;

XIDUSN XIDSLOT

------ -------

8 2

分解結果與第一個腳本直接查出來的XIDUSN與XIDSLOT相同,而TX鎖的ID2 (5861)

與XIDSQN相同,可見當LOCK TYPE 為TX 時,ID1 實際上是該事務所占用的回滾段段號

與事務表中的槽(SLOT)號的組合,ID2 即為該槽被重用的次數,而這三個值實際上可以

唯一地標識一個事務,即TRANSACTION ID,這三個值從系統表 v$transaction 中也可查到。

另外, DEPT 表中有 4 條記錄被鎖定,但 TX 鎖只有 1 個,這也與上面的理論分析一

致。繼續進行操作:

SESS#2:

SQL> update dept set loc=loc where deptno=20;

該更新語句被阻塞,此時再查看系統的鎖情況:

SESS#3:

SQL> @showlock

O_NAME SID LOCK_TYPE OBJECT_NAME XIDUSN XIDSLOT XIDSQN ---------- ----- --------------- --------------- ------ ------- ------

SCOTT 17 Row share DEPT 8 2 5861

SCOTT 19 Row Exclusive DEPT 0 0 0

SQL> @showalllock

SID TY ID1 ID2 LOCK_TYPE REQUEST CTIME BLOCK

----- -- ---------- ---------- --------------- ---------- ---------- ----------

17 TX 524290 5861 Exclusive 0 3462 1

17 TM 32970 0 Row share 0 3462 0

19 TM 32970 0 Row Exclusive 0 7 0

19 TX 524290 5861 None 6 7 0

在 DEPT 表上除了 SESS#1(SID 為 17)持有Row share 鎖外,又增加了 SESS#2(SID

為19)持有的Row Exclusive 鎖,但還沒有為SESS#2 分配回滾段(XIDUSN、XIDSLOT、

XIDSQN 的值均為 0);而從第二個腳本看到,SESS#2 的 TX 鎖的 LOCK_TYPE 為 None,

其申請的鎖類型(REQUEST)為 6(即 Exclusive),而其 ID1、ID2 的值與 SESS#1 所持有

的 TX 鎖的 ID1、ID2 相同,SESS#1 的 TX 鎖的阻塞域(BLOCK)為 1,這就說明了由于

SESS#1 持有的 TX 鎖,阻塞了 SESS#2 的更新操作(SESS#2 所更新的行與SESS#1 所鎖定

的行相沖突)。還可以看出,SESS#2 先申請表級的 TM鎖,后申請行(事務)級的TX 鎖,

這也與前面的理論分析一致。

下面,將SESS#1的事務進行回滾,解除對SESS#2 的阻塞,再對系統進行監控。

SESS#3:

SQL> @showlock

O_NAME SID LOCK_TYPE OBJECT_NAME XIDUSN XIDSLOT XIDSQN

---------- ----- --------------- --------------- ------ ------- ------

SCOTT 19 Row Exclusive DEPT 2 10 5803

SQL> @showalllock

SID TY ID1 ID2 LOCK_TYPE REQUEST CTIME BLOCK

----- -- ---------- ---------- --------------- ---------- ---------- ----------

19 TX 131082 5803 Exclusive 0 157 0

19 TM 32970 0 Row Exclusive 0 333 0

可以看到,SESS#1 的事務所持有的鎖已經釋放,系統為SESS#2的事務分配了回滾段,

而其TX 鎖也已經獲得,并且 ID1、ID2是其真正的 Transaction ID。再將會話 2 的事務進行

回滾。

SESS#2:

SQL> rollback;

Rollback complete.

檢查系統鎖的情況:

SESS#3:

SQL> @showlock

no rows selected

SQL> @showalllock

no rows selected

可以看到,TM與TX鎖已全部被釋放。 4.2 實體完整性引發的鎖阻塞

DEPT(部門)表有如下字段 DEPTNO(部門編號),DNAME(部門名稱),LOC(部

門位置);其中DEPTNO列為主鍵。

SESS#1

SQL> INSERT INTO DEPT(DEPTNO) VALUES(50);

1 row created.

SESS#3

SQL> @showlock

O_NAME SID LOCK_TYPE OBJECT_NAME XIDUSN XIDSLOT XIDSQN

---------- ----- --------------- --------------- ------ ------- ------

SCOTT 7 Row Exclusive DEPT 6 88 29

SQL> @showalllock

SID TY ID1 ID2 LOCK_TYPE REQUEST CTIME BLOCK

----- -- ---------- ---------- --------------- ---------- ---------- ----------

7 TX 393304 29 Exclusive 0 6 0

7 TM 3574 0 Row Exclusive 0 6 0

向 DEPT 表中插入一條DEPTNO 為50 的記錄后,SESS#1(SID為 7)在DEPT表上獲

得Row Exclusive鎖,并且由于進行了數據插入,該事務被分配了回滾段,獲得 TX鎖。

SESS#2

INSERT INTO DEPT(DEPTNO) VALUES(50);

這時,SESS#2(SID 為8)也向DEPT表中插入一條DEPTNO為 50的記錄,該語句被

阻塞,檢查鎖情況:

SESS#3

SQL> @showlock

O_NAME SID LOCK_TYPE OBJECT_NAME XIDUSN XIDSLOT XIDSQN

---------- ----- --------------- --------------- ------ ------- ------

SCOTT 8 Row Exclusive DEPT 7 75 30

SCOTT 7 Row Exclusive DEPT 6 88 29

SQL> @showalllock

SID TY ID1 ID2 LOCK_TYPE REQUEST CTIME BLOCK

----- -- ---------- ---------- --------------- ---------- ---------- ----------

7 TX 393304 29 Exclusive 0 92 1

7 TM 3574 0 Row Exclusive 0 92 0

8 TX 458827 30 Exclusive 0 22 0

8 TM 3574 0 Row Exclusive 0 22 0

8 TX 393304 29 None 4 22 0

SESS#2 在 DEPT 表上也獲得了 Row Exclusive 鎖,同樣也獲得了回滾段的分配,得到

TX 鎖,但是由于其插入的記錄與 SESS#1 插入的記錄的 DEPTNO 均為 50,該語句成功與

否取決于 SESS#1 的事務是提交還是回滾,所以 SESS#2 被阻塞,表現為 SESS#2 以 Share

方式(REQUEST=4)等待 SESS#1 所持有的TX鎖的釋放。

這時,如果SESS#1進行回滾:

SESS#1 SQL> ROLLBACK;

Rollback complete.

SESS#2

1 row created.

SESS#3

SQL> @showlock

O_NAME SID LOCK_TYPE OBJECT_NAME XIDUSN XIDSLOT XIDSQN

---------- ----- --------------- --------------- ------ ------- ------

SCOTT 8 Row Exclusive DEPT 7 75 30

SQL> @showalllock

SID TY ID1 ID2 LOCK_TYPE REQUEST CTIME BLOCK

----- -- ---------- ---------- --------------- ---------- ---------- ----------

8 TX 458827 30 Exclusive 0 136 0

8 TM 3574 0 Row Exclusive 0 136 0

SESS#2的阻塞將被解除, SESS#2 只持有原先已有的TM與TX 鎖,其等待的TX 鎖(由

SESS#1持有)也消失了。

如果SESS#1提交而不是回滾,在 SESS#2上將會出現如下提示:

ERROR at line 1:

ORA-00001: unique constraint (SCOTT.PK_DEPT) violated 錯誤。

即發生主鍵沖突,SESS#1與SESS#2 的所有鎖資源均被釋放。

4.3 參照完整性引發的鎖阻塞

EMP(員工)表有如下字段:EMPNO(員工編號),ENAME(員工姓名),DEPTNO

(員工所在部門編號),其中 DEPTNO 列為外鍵,其父表為 DEPT。

SESS#1

SQL> insert into dept(deptno) values(60);

1 row created.

SESS#3

SQL> @showlock

O_NAME SID LOCK_TYPE OBJECT_NAME XIDUSN XIDSLOT XIDSQN

---------- ----- --------------- --------------- ------ ------- ------

SCOTT 7 Row Exclusive DEPT 2 6 33

SQL> @showalllock

SID TY ID1 ID2 LOCK_TYPE REQUEST CTIME BLOCK

----- -- ---------- ---------- --------------- ---------- ---------- ----------

7 TX 131078 33 Exclusive 0 148 0

7 TM 3574 0 Row Exclusive 0 148 0

SESS#1(SID 為 7)在 DEPT 表中先插入一條 DEPTNO 為 60 的記錄,SESS#1 獲得了

DEPT表上的Row Exclusive 鎖,及一個TX鎖。

SESS#2

insert into emp(empno,deptno) values(2000,60);

被阻塞

SESS#3 SQL> @showlock

O_NAME SID LOCK_TYPE OBJECT_NAME XIDUSN XIDSLOT XIDSQN

---------- ----- --------------- --------------- ------ ------- ------

SCOTT 7 Row Exclusive DEPT 2 6 33

SCOTT 8 Row Exclusive EMP 3 20 31

SQL> @showalllock

SID TY ID1 ID2 LOCK_TYPE REQUEST CTIME BLOCK

----- -- ---------- ---------- --------------- ---------- ---------- ----------

7 TX 131078 33 Exclusive 0 228 1

7 TM 3574 0 Row Exclusive 0 228 0

8 TX 196628 31 Exclusive 0 9 0

8 TM 3576 0 Row Exclusive 0 9 0

8 TX 131078 33 None 4 9 0

SESS#2(SID 為 8)向 EMP 表中出入一條新記錄,該記錄 DEPT 值為 60(即 SESS#1

剛插入,但還未提交的記錄的DEPTNO值), SESS#2 獲得了EMP 表上的Row Exclusive 鎖,

另外由于插入記錄,還分配了回滾段及一個TX 鎖,但由于 SESS#2 的插入語句是否成功取

決于SESS#1的事務是否進行提交,所以它被阻塞,表現為 SESS#2 以Share(REQUEST=4)

方式等待SESS#1釋放其持有的 TX鎖。這時SESS#1 如果提交,SESS#2的插入也將執行成

功,而如果SESS#1 回滾,由于不符合參照完整性,SESS#2 將報錯:

SESS#2

insert into emp(empno,deptno) values(2000,60)

*

ERROR at line 1:

ORA-02291: integrity constraint (SCOTT.FK_DEPTNO) violated - parent key not

Found

SESS#2持有的鎖也被全部釋放。

4.4 外鍵未加索引引發的鎖阻塞

EMP 表上的DEPTNO 列為外鍵,但沒有在該列上建索引。

SESS#1

SQL> delete emp where 0=1;

0 rows deleted.

SESS#3:

SQL> @showlock

O_NAME SID LOCK_TYPE OBJECT_NAME XIDUSN XIDSLOT XIDSQN

---------- ----- --------------- --------------- ------ ------- ------

SCOTT 7 Row Exclusive EMP 0 0 0

SQL> @showalllock

SID TY ID1 ID2 LOCK_TYPE REQUEST CTIME BLOCK

----- -- ---------- ---------- --------------- ---------- ---------- ----------

7 TM 3576 0 Row Exclusive 0 10 0

首先SESS#1(SID為7)做了一個刪除操作,但由于條件(0=1)為永假,所以實際上

并沒有一行被刪除,從監控腳本可以看出SESS#1在 EMP 表上獲得Row Exclusive 鎖,但由于沒有實際的行被刪除,所以并沒有TX鎖,也沒有為 SESS#1分配回滾段。

SESS#2:

SQL> delete dept where 0=1;

該語句雖然也不會刪除實際數據,但卻被阻塞,查看系統的鎖情況:

SESS#3:

SQL> @showlock

O_NAME SID LOCK_TYPE OBJECT_NAME XIDUSN XIDSLOT XIDSQN

---------- ----- --------------- --------------- ------ ------- ------

SCOTT 8 None EMP 0 0 0

SCOTT 7 Row Exclusive EMP 0 0 0

SQL> @showalllock

SID TY ID1 ID2 LOCK_TYPE REQUEST CTIME BLOCK

----- -- ---------- ---------- --------------- ---------- ---------- ----------

7 TM 3576 0 Row Exclusive 0 31 1

8 TM 3576 0 None 4 12 0

SESS#2申請在EMP 表上加SHARE 鎖(REQUEST=4),但該申請被SESS#1阻塞,因

為SESS#1 已經在EMP 表上獲得了Row Exclusive 鎖,與SHARE鎖不相容。

下面我們對SESS#1進行回滾后,再進行監控。

SESS#3:

SQL> @showlock

O_NAME SID LOCK_TYPE OBJECT_NAME XIDUSN XIDSLOT XIDSQN

---------- ----- --------------- --------------- ------ ------- ------

SCOTT 8 Share EMP 0 0 0

SCOTT 8 Row Exclusive DEPT 0 0 0

SQL> @showalllock

SID TY ID1 ID2 LOCK_TYPE REQUEST CTIME BLOCK

----- -- ---------- ---------- --------------- ---------- ---------- ----------

8 TM 3574 0 Row Exclusive 0 16 0

8 TM 3576 0 Share 0 16 0

SESS#2在EMP 表上獲得Share鎖后,又在DEPT 表上獲得Row Exclusive 鎖,由于沒

有實際的行被修改,SESS#2 并沒有獲得TX 鎖。

在 Oracle8中,如果子表的外鍵上沒有加索引,當在父表上刪除記錄時,會先在子表上

申請獲得 Share 鎖,之后再在父表上申請 Row Exclusive 鎖。由于表級 Share 鎖的封鎖粒度

較大,所以容易引起阻塞,從而造成性能問題。

當在外鍵上建立索引后,在父表上刪除數據將不再對子表上加 Share鎖,如下所示:

SESS#1:

SQL> create index i_emp_deptno on emp(deptno);

Index created.

SQL> delete dept where 0=1;

0 rows deleted.

SQL>

SQL> @showlock

O_NAME SID LOCK_TYPE OBJECT_NAME XIDUSN XIDSLOT XIDSQN

---------- ----- --------------- --------------- ------ ------- ------

SCOTT 7 Row Exclusive DEPT 0 0 0

SQL> @showalllock

SID TY ID1 ID2 LOCK_TYPE REQUEST CTIME BLOCK

----- -- ---------- ---------- --------------- ---------- ---------- ----------

7 TM 3574 0 Row Exclusive 0 9 0

可以看到,在 EMP 表 DEPTNO 列上建立索引后,在 DEPT 表上執行 DELETE 操作,

不再要求在EMP 表上加Share鎖,只是在DEPT表上加 Row Exclusive鎖,封鎖的粒度減小,

引起阻塞的可能性也減小。

5.總結

Oracle數據庫通過具有意向鎖的多粒度封鎖機制進行并發控制,保證數據的一致性。其 DML

鎖(數據鎖)分為兩個層次(粒度):即表級和行級。通常的 DML 操作在表級獲得的只是

意向鎖(RS或RX),其真正的封鎖粒度還是在行級;另外,在Oracle數據庫中,單純地讀

數據(SELECT)并不加鎖,這些都極大地提高了系統的并發程度。

在支持高并發度的同時,Oracle數據庫利用意向鎖及數據行上加鎖標志位等設計技巧,減小了

Oracle維護行級鎖的開銷,使其在數據庫并發控制方面的優勢愈加明顯。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲欧洲成视频免费观看| 日韩精品视频三区| 久热99视频在线观看| 伦伦影院午夜日韩欧美限制| 成人在线国产精品| 国产欧美日韩精品在线观看| 深夜精品寂寞黄网站在线观看| 国产精品一香蕉国产线看观看| 欧美三级免费观看| 国产精品久久久91| 色综合久久久888| 91久久在线视频| 亚洲精品视频中文字幕| 亚洲电影中文字幕| 欧美韩日一区二区| 欧美黄色三级网站| 亚洲国产精品yw在线观看| 精品久久久久久久久久ntr影视| 欧美电影免费观看网站| 国产精品一区二区久久精品| 在线电影欧美日韩一区二区私密| 在线成人一区二区| 日韩欧美精品网站| 国产成人精彩在线视频九色| 亚洲图中文字幕| 欧美电影院免费观看| 最新国产精品亚洲| 青青草精品毛片| 日韩最新中文字幕电影免费看| 国产综合在线看| 欧美午夜女人视频在线| 日韩高清电影免费观看完整| 中文字幕精品一区久久久久| 91人人爽人人爽人人精88v| 久久久av网站| 国产欧美日韩专区发布| 欧美大片欧美激情性色a∨久久| 亚洲大胆人体在线| 中文字幕一区二区精品| 亚洲a在线观看| 成人午夜高潮视频| 精品亚洲一区二区三区四区五区| 欧美激情视频一区二区三区不卡| 国产激情久久久久| 欧美国产日韩免费| 欧美性猛交xxxx富婆弯腰| 亚洲xxxx3d| 理论片在线不卡免费观看| 日韩精品在线影院| 亚洲一区二区三区久久| 国产午夜精品全部视频播放| 精品久久久免费| 在线亚洲午夜片av大片| 92看片淫黄大片欧美看国产片| 国产美女高潮久久白浆| 91在线观看欧美日韩| 日韩av片电影专区| 国产在线观看一区二区三区| 欧美成人h版在线观看| 91在线视频九色| 亚洲第一国产精品| 亚洲激情免费观看| 亚洲视频在线免费观看| 日韩一区二区三区国产| 欧美日韩国产精品专区| 成人国产精品一区| 国产精品露脸自拍| 欧美激情精品久久久久久免费印度| 亚洲精品一区二三区不卡| 最近中文字幕2019免费| 日韩av电影院| 亚洲最大在线视频| 中文字幕久久精品| 欧美电影在线观看| 国产精品天天狠天天看| 久久久国产精品x99av| 国产福利视频一区二区| 亚洲国产精品99久久| 久久久精品久久久| 在线日韩日本国产亚洲| 91精品久久久久久综合乱菊| 欧美另类极品videosbest最新版本| 国产综合视频在线观看| 97热在线精品视频在线观看| 91精品国产沙发| 成人97在线观看视频| 中文字幕日韩av综合精品| 一区二区三区精品99久久| 国产成人高潮免费观看精品| 91影视免费在线观看| 国精产品一区一区三区有限在线| 日韩精品极品在线观看播放免费视频| 国产欧美一区二区三区久久| 日韩成人在线视频网站| 久久国内精品一国内精品| 成人av.网址在线网站| 国产成人一区二区三区| 插插插亚洲综合网| 国产精品亚洲第一区| 亚洲乱码国产乱码精品精天堂| 青草青草久热精品视频在线网站| 亚洲欧洲高清在线| 久久国产精彩视频| 欧美老肥婆性猛交视频| 国产精自产拍久久久久久| 国产欧美一区二区白浆黑人| 久久av在线看| 91在线国产电影| 日韩最新免费不卡| 久久久精品国产一区二区| 欧美亚洲成人免费| 色综合色综合网色综合| 日韩精品在线免费播放| 国产一区二中文字幕在线看| 在线看片第一页欧美| 亚洲xxxxx电影| 亚洲毛片在线免费观看| 久久久999国产精品| 亚洲成人国产精品| 亚洲直播在线一区| 色综合久久中文字幕综合网小说| 欧美电影免费观看高清| 亚洲欧美国产制服动漫| 亚洲色图综合网| 在线视频精品一| 亚洲欧洲视频在线| 色婷婷av一区二区三区在线观看| 国产成人一区二区| 国产精品久久久久久久久久东京| 亚洲美女中文字幕| 久久国产加勒比精品无码| 国产亚洲aⅴaaaaaa毛片| 久久久久久综合网天天| 国产欧美精品一区二区三区-老狼| 亚洲天堂av在线免费| 欧美成在线观看| 久久久久久69| 久久97久久97精品免视看| 久久久天堂国产精品女人| 亚洲第一在线视频| 欧美激情视频在线免费观看 欧美视频免费一| 91po在线观看91精品国产性色| 一区二区三区视频免费在线观看| 日本欧美精品在线| 成人午夜激情网| 日韩av在线免费看| 精品国产一区二区三区四区在线观看| 欧美日韩美女视频| 久久精品国产亚洲精品2020| 国产精品jvid在线观看蜜臀| 亚洲欧美精品伊人久久| 国产精品88a∨| 国产精品大片wwwwww| 国产欧美一区二区三区久久人妖| 亚洲国产毛片完整版| 大胆人体色综合| 久久亚洲精品成人| 国产精品一区二区av影院萌芽| 538国产精品一区二区在线| 国产免费一区视频观看免费| 欧美激情videoshd| 中文在线不卡视频| 98精品国产自产在线观看| 成人日韩在线电影|