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;


猜你喜欢

转载自blog.csdn.net/Paul_George/article/details/80396771