Oracle-24-鎖機制

DDL鎖:保護數據結構,保護對象的完整性,也叫字典鎖。

當我們想要向表中增加一列,要求我們先要鎖定表的結構,然後增加一個新的列。

select table_name,table_lock from user_tables;
TABLE_NAME                     TABLE_LO
------------------------------ --------
DEPT                           ENABLED
EMP                            ENABLED
BONUS                          ENABLED
SALGRADE                       ENABLED

Elapsed: 00:00:00.11

創建一張臨時表

create table e01 as select * from emp;
select table_name,table_lock from user_tables;
TABLE_NAME                     TABLE_LO
------------------------------ --------
DEPT                           ENABLED
EMP                            ENABLED
BONUS                          ENABLED
SALGRADE                       ENABLED
E01                            ENABLED

Elapsed: 00:00:00.02
alter table e01 disable table lock;
select table_name,table_lock from user_tables;
TABLE_NAME                     TABLE_LO
------------------------------ --------
DEPT                           ENABLED
EMP                            ENABLED
BONUS                          ENABLED
SALGRADE                       ENABLED
E01                            DISABLED

Elapsed: 00:00:00.03

現在表鎖處於DISABLE狀態

下面我們對錶做一些操作

truncate table e01;
truncate table e01
               *
ERROR at line 1:
ORA-00069: cannot acquire lock -- table locks disabled for E01


Elapsed: 00:00:00.03
drop table e01;
drop table e01
           *
ERROR at line 1:
ORA-00069: cannot acquire lock -- table locks disabled for E01


Elapsed: 00:00:00.12

我們把鎖打開

alter table e01 enable table lock;
select table_name,table_lock from user_tables;
TABLE_NAME                     TABLE_LO
------------------------------ --------
DEPT                           ENABLED
EMP                            ENABLED
BONUS                          ENABLED
SALGRADE                       ENABLED
E01                            ENABLED

Elapsed: 00:00:00.02
truncate table e01;
Table truncated.

Elapsed: 00:00:00.09


DML鎖:在事務中產生的,爲了保證併發數據一致性的鎖,存在於行頭,叫做行級鎖

用sys用戶授予scott用戶查看視圖權限

grant select on v_$mystat to scott;

查看當前會話的sid

select sid from v$mystat where rownum=1;
       SID
----------
        38

Elapsed: 00:00:00.00

在sys用戶下查看該會話有哪些鎖

select * from v$lock where sid=38;
ADDR             KADDR                   SID TY        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK
---------------- ---------------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
000000009705A0A8 000000009705A100         38 AE        100          0          4          0       1822     0
000000009705A248 000000009705A2A0         38 TO      65927          1          3          0        425     0

Elapsed: 00:00:00.03

SCOTT用戶模擬會話產生鎖

insert into e01 select * from emp;

SYS用戶查看鎖的狀態

select * from v$lock where sid=38;
ADDR             KADDR                   SID TY        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK
---------------- ---------------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
000000009705A0A8 000000009705A100         38 AE        100          0          4          0       2014     0
000000009705A248 000000009705A2A0         38 TO      65927          1          3          0        617     0
00007FAEC3237828 00007FAEC3237888         38 TM      74754          0          3          0         52     0
0000000096383280 00000000963832F8         38 TX     786441          6          6          0         48     0

Elapsed: 00:00:00.00

我們隊SCOTT用戶事務進行提交

commit;

再查看鎖的狀態

select * from v$lock where sid=38;
ADDR             KADDR                   SID TY        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK
---------------- ---------------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
000000009705A0A8 000000009705A100         38 AE        100          0          4          0       2112     0
000000009705A248 000000009705A2A0         38 TO      65927          1          3          0        715     0

Elapsed: 00:00:00.00

Oracle是自動管理鎖的資源的,在不同時間對不同對象操作就會產生不同的鎖,如果兩個會話同時修改一張表的同一行信息,會出現鎖的徵用問題,他們會以隊列的形式進行排隊處理

我們開啓兩個SCOTT用戶的會話同時執行一個SQL

update e01 set sal=sal+1 where empno=7369;

我們用SYS用戶來看下鎖隊列的情況

@?/rdbms/admin/utllockt
drop table lock_holders
           *
ERROR at line 1:
ORA-00942: table or view does not exist


Elapsed: 00:00:00.00

Table created.

Elapsed: 00:00:00.02
drop   table dba_locks_temp
             *
ERROR at line 1:
ORA-00942: table or view does not exist


Elapsed: 00:00:00.00

Table created.

Elapsed: 00:00:00.03

1 row created.

Elapsed: 00:00:00.00

Commit complete.

Elapsed: 00:00:00.01

Table dropped.

Elapsed: 00:00:00.03

1 row created.

Elapsed: 00:00:00.00

Commit complete.

Elapsed: 00:00:00.00

WAITING_SESSION   LOCK_TYPE         MODE_REQUESTED MODE_HELD      LOCK_ID1          LOCK_ID2
----------------- ----------------- -------------- -------------- ----------------- -----------------
36                None
   38             Transaction       Exclusive      Exclusive      1310747           6

Elapsed: 00:00:00.00

Table dropped.

Elapsed: 00:00:00.03

如果出現兩個會話交叉入隊,都在等待另一方把鎖放開,Oracle會中斷其中的一個會話,這種情況叫死鎖。

我們手工將處於資源等待的會話殺掉

select sid,serial# from v$session where sid=38;
       SID    SERIAL#
---------- ----------
        38          6

Elapsed: 00:00:00.00
alter system kill session '38,6' immediate;


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章