日常工作中偶尔会遇到锁表的情况,每次锁表都要在网上或笔记中去找语句进行处理。在这里做一个汇总,方便以后查阅。
当然锁表大多数情况肯定是代码不健康导致的。对症下药,处理异常逻辑应该放在第一位。
锁表原理
数据库使用独占式*机制,当执行insert update delete时,对表进行锁住,直到发生 commite 或者 回滚 或者 退出数据库用户。
如 当A程序执行了对 tableA 的 insert,并还未 commite 时,B程序也对 tableA 进行 insert,则此时会发生资源正忙的异常,就是锁表。
Oracle锁表时用
查看锁表进程SQL语句:
语句1:被锁对象表、数据库对象表、数据session表关联来获取被锁对象对应的是那个session
select sess.sid,
sess.serial#,
lo.oracle_username,
lo.os_user_name,
ao.object_name,
lo.locked_mode
from v$locked_object lo,
dba_objects ao,
v$session sess
where ao.object_id = lo.object_id and lo.session_id = sess.sid;
语句2:
select * from v$session t1, v$locked_object t2 where t1.sid = t2.SESSION_ID;
查看导致锁表的sql语句是那一条
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#;
杀掉锁表进程
通过上面的查询获取SID和serial#,替换下面的x,y,就可以解除被锁的状态
alter system kill session 'x,y';
SqlServer锁表时用
查询锁表id
spid :被锁进程ID
tableName:发生死锁的表名
SELECT request_session_id spid,OBJECT_NAME(resource_associated_entity_id)tableName FROM sys.dm_tran_locks WHERE resource_type='OBJECT '
使用kill关键字来杀掉被锁的进程ID就可以对表进行解锁
KILL 99