通过得到的rowid,可以查询到具体记录:
HELLODBA.COM> select * from tx_lock_tab where rowid = chartorowid('AAAwW6AAFAAAQcmAAB');
A B C
---------- - --------------------
100 C AOAKAPSOD
死锁分析
对于此类锁所引发的死锁问题,通过Trace文件可以很快定位出来。首先,我们可以通过锁的请求、持有模式(x)可以知道这是行级锁:
---------Blocker(s)-------- ---------Waiter(s)---------
Resource Name process session holds waits process session holds waits
TX-000a005e-0016ce18 231 197 X 295 305 X
TX-000e001d-00496580 295 305 X 591 569 X
TX-00040016-001d820b 591 569 X 574 510 X
TX-00030002-001fadc2 574 510 X 231 197 X
同时,我们还可以找到导致死锁的语句、执行语句的用户、客户端及模块信息:
Current SQL statement for this session:
UPDATE CSS_CARRIER SET REC_UPD_DT = TO_TIMESTAMP (:"SYS_B_0", :"SYS_B_1") WHERE (CARRIER_ID = :"SYS_B_2")
...
Information on the OTHER waiting sessions:
Session 305:
pid=295 serial=186 audsid=902537392 user: 33/CSSJAVA
O/S info: user: oracle, term: unknown, ospid: , machine: as04.cargosmart.com
program: JDBC Thin Client
application name: JDBC Thin Client, hash value=0
Current SQL Statement:
UPDATE CSS_CARRIER SET REC_UPD_DT = TO_TIMESTAMP (:"SYS_B_0", :"SYS_B_1") WHERE (CARRIER_ID = :"SYS_B_2")
...
End of information on OTHER waiting sessions.
此外,还能知道锁所在的对象和数据记录(ROWID):
Rows waited on:
Session 305: obj - rowid = 00005B9A - AAAFuaABBAAAAaKAAI
(dictionary objn - 23450, file - 65, block - 1674, slot - 8)
Session 569: obj - rowid = 00005B9A - AAAFuaABBAAAAaKABU
(dictionary objn - 23450, file - 65, block - 1674, slot - 84)
Session 510: obj - rowid = 00005B9A - AAAFuaABBAAAAaKAAQ
(dictionary objn - 23450, file - 65, block - 1674, slot - 16)
Session 197: obj - rowid = 00005B9A - AAAFuaABBAAAAaKAAF
(dictionary objn - 23450, file - 65, block - 1674, slot - 5)
然后再通过以上语句及会话的其它信息,找到相应代码,结合数据对象及产生锁的记录分析逻辑过程,修正会导致死锁的代码。
解决方法
要解决等待会话被“僵死”的问题,关键要看导致阻塞的会话正在做什么、或者正在等待什么,找到其事务长时间不提交的根本原因:
select s.sid, s.event, s.wait_time, q.sql_text
from v$session s, v$sqlarea q
where s.sql_address = q.address(+)
and s.sql_hash_value = q.hash_value(+)
and s.sid = 129;
根本解决方法就是要调整应用逻辑,避免死锁。
例如,我们有一个案例:一个应用是多线程服务的,当收到请求事件后,服务进程会打开一个游标,对游标中数据逐一进行业务处理、统一更新。由于不同进程打开游标的时间不同,游标查询语句获取的数据顺序也会不同,因此这个应用经常抛出死锁错误。我们给出的解决方案就是在游标查询语句中加入排序,使更新数据按某一特定顺序进行,从而避免死锁。
上一页 [1] [2] [3]
责任编辑:小草