Article Directory
1 Overview
1.1 Mind Map
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:
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:
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:
4 - share(s) - share table lock
Example:
lock table scott.test in share mode nowait;
Test screenshot:
5- s/row-s(ssx) - share row exclusive table lock
Example:
lock table scott.test in share row exclusive mode nowait;
Test Results:
6 - exclusive(x) - exclusive table lock
Example:
lock table scott.test in exclusive mode nowait;
Test screenshot:
3.2 for update skip locked
日常中,我们常用的锁语句有如下:
insert
update
delete
select ... for update
解锁语句如下:
commit
rollback
Expansion: