第十课
会话必须先锁定要修改的数据,之后数据库才允许会话修改相应数据。
事务处理可以锁定单个数据行、多个数据行、甚至整个表。Oracle DB 支持手动锁定和自动锁定。
Oracle实例使用多种类型的锁来保持内部一致性。本课只重点介绍用于保护行和表的锁定机制。
事务处理修改数据时会获取行级锁,而不是块级或表级锁。修改对象(如表移动)时会获取对象级锁,而不是整个数据库锁或方案锁。
如果多个事务需要锁定同一资源,则第一个请求锁的事务处理会获得锁。其它事务处理将等待,直到第一个事务处理完成为止。
排队机制是自动进行。
事务处理完成(即发出COMMIT 或ROLLBACK)时,将释放所有锁。
默认情况下,锁定机制采用细粒度行级锁定模式。
可避免在进行更改时另一会话锁定整个表(drop、truncate)。
SQL> desc v
m
y
s
t
a
t
;
(
查
看
会
话
s
i
d
)
S
Q
L
>
s
e
l
e
c
t
d
i
s
t
i
n
c
t
s
i
d
f
r
o
m
v
mystat;(查看会话sid) SQL> select distinct sid from v
mystat;(查看会话sid)SQL>selectdistinctsidfromvmystat;(查看会话sid)
select * from v$lock;可以查询
这种情况下,用户要尝试执行事务处理1:就一定要与管理员联系以获得帮助,DBA 必须检测冲突并解决冲突。
ALTER SYSTEM KILL SESSION ‘250,58719’ IMMEDIATE
检测锁冲突:
持有锁的会话位于顶层,下面是排队请求锁的会话。
select * from v$session where sid='40';
select * from v$process where addr='000000006BAD45D8';
[oracle@ouzy ~]$ ps -ef|grep 22009
[oracle@ouzy ~]$ kill -9 22009(结束会话)
alter system kill session '3417,17123' immediate;
SELECT sid, serial#, username, blocking_session
FROM v$session
WHERE sid IN ('42', '48', '35');
select * from v$locked_object;
死锁是锁冲突的一种特殊情况。
Oracle会自动检测死锁并终止发生错误的语句。
alertSID.log记录死锁:
扩展:
v$lock
type: TM - DML enqueue表锁,DML锁
TX - Transaction enqueue 行锁,事务锁
UL - User supplied
lmode: 0 - none
1 - null (NULL)
2 - row-S (SS):行级共享锁
3 - row-X (SX):行级排他锁,update行
4 - share (S):共享锁
5 - S/Row-X (SSX):共享行级排他锁
6 - exclusive (X):排他锁
6: lock table t in exclusive mode;(表锁)
select * from v$locked_object
4: lock table t in share mode;
2: lock table t in row share mode;
5: lock table t in share row exclusive mode;
3: lock table t in row exclusive mode;
create index:获取共享锁
alter table、drop table、drop index、truncate table获取排它锁。
进行dml操作时不能drop、truncate表。
谁阻塞谁?源头是哪里?
update t set object_name=‘t1’ where object_id=1000;
update t set object_name=‘t2’ where object_id=1000;
update t set object_name=‘t3’ where object_id=1000;
select * from v$locked_object;
select blocking_session,sid,event from v$session where blocking_session is not null;
select * from v$session_wait;可以查询等待的时间
select sid,prev_exec_start,sql_exec_start from v$session t where sid in (9,2283,3411);
SELECT b.sid,
a.sql_id,
a.sql_text,
a.hash_value,
b.username,
b.machine,
a.module,
c.block,
c.request,
d.seconds_in_wait
FROM v$sql a, v$session b, v$lock c, v$session_wait d
WHERE c.type = 'TX'
AND a.sql_id = b.sql_id
AND b.sid = c.sid
AND d.sid = b.sid
UNION ALL
SELECT b.sid,
a.sql_id,
a.sql_text,
a.hash_value,
b.username,
b.machine,
a.module,
c.block,
c.request,
d.seconds_in_wait
FROM v$sql a, v$session b, v$lock c, v$session_wait d
WHERE c.type = 'TX'
AND a.sql_id = b.prev_sql_id
AND b.sid = c.sid
AND d.sid = b.sid
AND c.block = 1