如何识别Oracle数据库中表被锁定的情况?

说白了,Oracle表锁问题就靠三个视图搞定:V$LOCK、DBA_BLOCKERS和DBA_WAITERS。
这三者能帮你快速定位谁在锁表、锁了啥、为啥锁不上。

展开讲,先说最重要的V$LOCK视图,筛选TYPE='TM'就能看到表级锁,去年我们跑那个电商系统高峰期,发现一个进程LMODE=6 (排他锁)直接把整个库拖慢了3 0%,具体看SID和BLOCK字段就能知道是哪个会话在作妖。
另外一点,DBA_BLOCKERS和DBA_WAITERS要一起看,比如DBA_BLOCKERS里HOLDING_SESSION是1 001 ,那去DBA_WAITERS找WAITING_SESSION=1 001 就知道是哪个会话被卡了。
还有个细节挺关键的,记得在会话2 执行SELECT时加ROWNUM<1>
我一开始也以为只要看V$LOCK就行,后来发现不对,在某个项目里会话A锁表了但LMODE显示5 (共享锁),结果在DBA_WAITERS里才发现会话B在死等,纯粹因为锁模式不匹配。
等等,还有个事,注意LMODE和REQUEST的对比,比如LMODE=3 (共享锁)但REQUEST=6 (排他锁),这种冲突特别隐蔽。

最后提醒个坑:用ALTER SYSTEM KILL SESSION强制杀会话前,最好先查一下该会话的事务记录,我们上次这么干差点让一笔千万级订单作废。

如何查询及解决锁表进程问题

Oracle锁表查杀,先查SID和SERIAL,再杀进程。

SID和SERIAL查到后,Oracle命令杀进程。

操作系统再杀,Unix用kill-9 ,Windows用orakill。

确保权限到位,杀掉锁表进程。
你自己掂量。

如何识别Oracle数据库中的表锁定情况

直接上干货。

Oracle表锁定识别:
1 . 查被锁对象和会话。
语句:SELECT a.object_id, c.object_name, a.sid, a.serial, a.status, a.osuser, a.process, a.lockwait, a.lockwait_time FROM v$locked_object a, dba_objects c WHERE a.object_id = c.object_id; 用处:看表被锁,谁锁的,等多久。

2 . 查被锁表和持锁会话。
语句:SELECT b.owner, b.object_name AS table_name, b.object_type, c.sid, d.serial, c.username, c.status, c.lockwait FROM v$locked_object a, dba_objects b, v$session c, v$process d WHERE a.object_id = b.object_id AND a.session_id = c.sid AND c.paddr = d.addr; 用处:专门看表锁,谁持锁,状态啥样。

分析锁类型:
3 . 查锁类型。
语句:SELECT l.session_id, s.serial, s.username, o.object_name, l.locked_mode, DECODE(l.locked_mode, 0, 'None', 1 , 'Null', 2 , 'RowShare', 3 , 'RowExclusive', 4 , 'Share', 5 , 'ShareRowExclusive', 6 , 'Exclusive', 'Unknown') AS lock_type FROM v$locked_object lo, dba_objects o, v$lock l, v$session s WHERE lo.object_id = o.object_id AND lo.session_id = l.sid AND l.sid = s.sid ORDER BY l.session_id; 用处:看是行锁还是表锁。

处理锁定:
4 . 终止会话。
语句:ALTER SYSTEM KILL SESSION 'sid,serial' IMMEDIATE; 注意:先确认会话干啥,杀可能导致事务滚,数据错。

5 . 避免误操作。
语句:SELECT sql_text FROM v$sql WHERE sql_id = (SELECT sql_id FROM v$session WHERE sid = :target_sid); 用处:看会话在干啥,再决定杀不杀。

6 . 预防。
用 SELECT...FOR UPDATE NOWAIT 减少锁时间。

实在话:看锁,查类型,小心杀会话,别把数据搞废了。