一、锁表的原因

锁表发生和原理
1、锁表发生在insertupdatedelete 中 。
2、锁表的原理是数据库使用独占式封锁机制,当执行上面的语句时,对表进行锁住,直到发生 commite 或者回滚 或者退出数据库用户 。

锁表的原因
1、A程序执行了对 tableAinsert ,并还未 commite 时,B程序也对 tableA 进行 insert 则此时会发生资源正忙的异常 就是锁表。
2、锁表常发生于并发而不是并行(并行时,一个线程操作数据库时,另一个线程是不能操作数据库的,cpui/o 分配原则)。

减少锁表的概率
1、减少insertupdatedelete 语句执行到 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';