Oracle lock detailed (lock)

1 Overview

1.1 Mind Map

Insert picture description here

2 categories

Classification (can jump to Oracle official documents) description
v$locked_object Describe DML lock information
dba_ddl_locks Describe DDL lock information
v$lock All lock information currently acquired

2.1 DML 锁 - v$locked_object

concept:

'共享锁[S 锁]',又称为 '读锁',获得 '共享锁' 后,可以查询但无法修改数据
	若事务 T 对数据对象 A 加了 S 锁,则事务 T 可以读 A,但不能修改 A,
    其它事务只能再对 A 加 'S 锁'(而不能加 X 锁),直到 T 释放 A 上的 S 锁
    这保证了其它事务可以 '读 A',但在 T 释放 A 上的 S 锁之前不能对 A 做任何修改
    
'排它锁[X 锁]':又称为 '写锁''独占锁',获得 '排它锁' 后,既可以查询又可以修改数据
	若事务 T 对数据对象 A 加了 X 锁,则事务 T 既可以读 A,又可以修改 A
	其它事务不能再对 A 加'任何锁',直到 T 释放 A 上的锁
	这保证了其它事务在 T 释放 A 上的锁之前 '不能再读取和修改 A'

Common queries:

SELECT lo.session_id 会话id,
       s.serial# 会话序列号,
       p.spid 会话进程号,
       s.username 所属用户,
       s.machine 客户端,
       do.object_name 被锁对象,
       do.object_type 被锁对象类型,
       ceil((SYSDATE - s.logon_time) * 24 * 60 * 60) "被锁时间(S)"
  FROM v$locked_object lo, -- object_id 
       v$session       s, -- saddr {sid }
       v$process       p, -- addr 
       dba_objects     do -- object_id 
 WHERE s.sid = lo.session_id
   AND p.addr = s.paddr
   AND do.object_id = lo.object_id
   AND s.schema# <> 0
-- AND s.username = '';

2.2 DDL 锁 - dba_ddl_locks

SELECT ddl_s.session_id 会话id,
       s.serial# 会话序列号,
       p.spid 会话进程号,
       s.username 所属用户,
       s.machine 客户端,
       do.object_name 被锁对象,
       do.object_type 被锁对象类型,
       ceil((SYSDATE - s.logon_time) * 24 * 60 * 60) "被锁时间(S)"
  FROM dba_ddl_locks ddl_s, -- session_id 
       v$session     s, -- saddr {sid }
       v$process     p, -- addr 
       dba_objects   do -- object_id 
 WHERE s.sid = ddl_s.session_id
   AND p.addr = s.paddr
   AND do.object_id = s.row_wait_obj#
   AND s.schema# <> 0
-- AND s.username = '';

2.3 All locks-v$lock

SELECT l.sid         "会话ID",
       s.serial#     "会话序列号",
       p.spid        "会话进程号",
       l.type        "锁类型",
       s.username    "所属用户",
       s.machine     "客户端",
       o.object_name "被锁对象",
       o.object_type "被锁对象类型",
       l.ctime       "被锁时间(S)"
  FROM v$lock      l, -- addr
       v$session   s, -- saddr 
       dba_objects o, -- object_id 
       v$process   p -- addr 
 WHERE s.sid = l.sid
   AND o.object_id = l.id1
   AND p.addr = s.paddr
   AND l.type IN ('TM', 'TX')  -- 我们只需要关注 TM / TX 锁即可
-- AND s.username = ''
;

3 example

3.1 DML lock details

  • Just understand this part.
  • The following grammars are given, if you are interested, please try it yourself
CREATE TABLE scott.test(
   ID   NUMBER,
   NAME VARCHAR2(30)
);

INSERT INTO scott.test(id, name) values(1, 'a');
COMMIT;
Lock mode Lock description Full name Explanation
0 none lock requested but not yet obtained The lock was requested but not obtained
1 null select query
2 rows_s(ss) row share lock Row-level shared lock
3 row_x(sx) row exclusive table lock Row exclusive table lock
4 share(s) share table lock Shared table lock
5 s/row-s(ssx) share row exclusive table lock Shared row exclusive table lock
6 exclusive(x) exclusive table lock Exclusive table lock

The larger the "lock mode" value, the more rows will be affected!

For detailed explanation, please refer to the locked mode link in the official Oracle document v$locked_object (Oracle Database Concepts …)

0-none-the lock has been requested but not obtained

session 1:

lock table scott.test in share mode nowait;

session 2:

update scott.test t set t.name = 'aa' where t.id = 1;

Test screenshot:
Insert picture description here

1 - null - select

2 - rows_s(ss) - row share lock

Grammar: (the same reasoning below, not repeat it)

lock table <表名>[, <表名>] in row share mode [nowait]
lock table <表名>[, <表名>] in share update mode [nowait];

nowait:被锁的语句会 '一直等待' 上一个获得锁的语句 '释放锁'
        指定 nowait,可以不用进行等待,直接反馈 'ORA-00054: 资源正忙 

Example:

lock table scott.test in row share mode nowait;

lock table scott.test in share update mode nowait;

Test screenshot:
Insert picture description here

3 - row_x(sx) - row exclusive table lock

select * from scott.test for update;

insert into scott.test(id, name) values(2, 'b');

update scott.test t set t.name = 'aa' where t.id = 1;

delete from scott.test t where t.id = 1;

Test screenshot:

Insert picture description here

4 - share(s) - share table lock

Example:

lock table scott.test in share mode nowait;

Test screenshot:
Insert picture description here

5- s/row-s(ssx) - share row exclusive table lock

Example:

lock table scott.test in share row exclusive mode nowait;

Test Results:
Insert picture description here

6 - exclusive(x) - exclusive table lock

Example:

lock table scott.test in exclusive mode nowait;

Test screenshot:
Insert picture description here

3.2 for update skip locked

日常中,我们常用的锁语句有如下:
insert
update
delete
select ... for update

解锁语句如下:
commit
rollback

Expansion:

Guess you like

Origin blog.csdn.net/qq_34745941/article/details/106939087