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;