Oracle锁机制实例讲解

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;
(0)
上一篇 2022年3月22日
下一篇 2022年3月22日

相关推荐