一、锁表的原因
锁表发生和原理
1、锁表发生在insert
、update
、delete
中 。
2、锁表的原理是数据库使用独占式封锁机制,当执行上面的语句时,对表进行锁住,直到发生 commite
或者回滚 或者退出数据库用户 。
锁表的原因
1、A程序执行了对 tableA
的 insert
,并还未 commite
时,B程序也对 tableA
进行 insert
则此时会发生资源正忙的异常 就是锁表。
2、锁表常发生于并发而不是并行(并行时,一个线程操作数据库时,另一个线程是不能操作数据库的,cpu
和 i/o
分配原则)。
减少锁表的概率
1、减少insert
、update
、delete
语句执行到 commite
之间的时间。具体点批量执行改为单个执行、优化 sql 自身的非执行速度。
2、如果异常对事物进行回滚。
二、查看锁表
第一种
-- 查看是否被锁表
SELECT
a.object_name,
b.session_id,
c.serial #,
c.program,
c.username,
c.command,
c.machine,
c.lockwait
FROM
all_objects a,
v$locked_object b,
v$session c
WHERE
a.object_id = b.object_id
AND c.sid = b.session_id;
-- 查看锁表的原因
SELECT
l.session_id sid,
s.serial#,
l.locked_mode,
l.oracle_username,
s.USER#,
l.os_user_name,
s.machine,
s.terminal,
a.sql_text,
a.action
FROM
v$sqlarea a,
v$session s,
v$locked_object l
WHERE
l.session_id = s.sid
AND s.prev_sql_addr = a.address
ORDER BY
sid,
s.serial#;
-- 解锁方法,146为锁住的进程号,即spid
ALTER system kill SESSION 'sid,serial#';
-- 查看被锁的表
SELECT
p.spid,
c.object_name,
b.session_id,
b.oracle_username,
b.os_user_name
FROM
v$process p,
v$session a,
v$locked_object b,
all_objects c
WHERE
p.addr = a.paddr
AND a.process = b.process
AND c.object_id = b.object_id
第二种
-- 查看是否有被锁的表:
select b.owner,b.object_name,a.session_id,a.locked_mode
from v$locked_object a,dba_objects b
where b.object_id = a.object_id
-- 查看是哪个进程锁的
select b.username,b.sid,b.serial#,logon_time
from v$locked_object a,v$session b
where a.session_id = b.sid order by b.logon_time
-- 杀掉进程
alter system kill session 'sid,serial#';
alter system kill session '426,4275';