锁表原因及解决思路
1、锁表发生在insert、update 、delete 中;
2、锁表的原理是数据库使用独占式封锁机制,当执行上面的语句时,对表进行锁住,直到发生commit 或者 回滚 或者退出数据库用户;
3、锁表的原因:第一、 A程序执行了对 tableA 的 insert ,并还未 commite时,B程序也对tableA 进行insert 则此时会发生资源正忙的异常 就是锁表,第二、锁表常发生于并发而不是并行(并行时,一个线程操作数据库时,另一个线程是不能操作数据库的,cpu 和i/o 分配原则);
4、减少锁表的概率:1、减少insert 、update 、delete 语句执行 到 commit 之间的时间。具体点批量执行改为单个执行、优化sql自身的非执行速度,2、如果异常对事物进行回滚。
注意事项
在使用Oracle SQL Developer执行修改数据库的SQL语句时,要记得在执行之后,要记得提交一下(Commit),否则很可能会造成锁表。 在锁表之后,如果你再对这张表进行修改方面的操作,在Oracle SQL Developer上的特征就是:忙碌执行中,换句话说,卡死了。
解决方案
以下几个为相关表
SELECT * FROM v$lock;
SELECT * FROM v$sqlarea;
SELECT * FROM v$session;
SELECT * FROM v$process ;
SELECT * FROM v$locked_object;
SELECT * FROM all_objects;
SELECT * FROM v$session_wait;
查看被锁的表
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;
查看连接的进程
SELECT sid, serial#, username, osuser FROM v$session;
查出锁定表的sid, serial#,os_user_name, machine_name, terminal,锁的type,mode
SELECT s.sid, s.serial#, s.username, s.schemaname, s.osuser, s.process, s.machine,
s.terminal, s.logon_time, l.type
FROM v$session s, v$lock l
WHERE s.sid = l.sid
AND s.username IS NOT NULL
ORDER BY sid;
这个语句将查找到数据库中所有的DML语句产生的锁,还可以发现,任何DML语句其实产生了两个锁,一个是表锁,一个是行锁。
--杀掉进程 sid,serial#
alter system kill session'210,11562';
--查询当前表空间各个表的数据量
Select Segment_Name,Sum(bytes)/1024/1024 neicun From User_Extents Group By Segment_Name;