必须在sqlplus中执行; ora-02049解决一例 =========================================================== 作者: guyeh(http://guyeh.itpub.net) 发表于:2008.09.10 16:25 分类: 数据库 出处:http://guyeh.itpub.net/post/34115/470617 ---------------------------------------------------------------
死锁是数据库经常发生的问题,数据库一般不会无缘无故产生死锁,死锁通常都是由于我们应用程序的设计本身造成的。产生死锁时,如何解决呢,下面是常规的解决办法:
1)执行下面SQL,先查看哪些表被锁住了: 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;
2)查处引起死锁的会话 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; 这里会列出SID
3) 查出SID和SERIAL#: 查V$SESSION视图: SELECT SID,SERIAL#,PADDR FROM V$SESSION WHERE SID='刚才查到的SID'; 这一步将得到PADDR
4)查V$PROCESS视图: SELECT SPID FROM V$PROCESS WHERE ADDR='刚才查到的PADDR'; 这一步得到SPID
5)杀死进程 (1)在数据库中,杀掉ORACLE进程: ALTER SYSTEM KILL SESSION '查出的SID,查出的SERIAL#';
执行存储过程更新一个表中的数据的时候产生如下的错误:
SQL> exec update_jc_kxx_yxrq;
begin update_jc_kxx_yxrq; end;
ORA-20998: Err=-2049,Msg=0-ORA-02049: 超时: 分布式事务处理等待锁定 ORA-06512: 在"ICUSER.UPDATE_JC_KXX_YXRQ", line 36 ORA-06512: 在line 2
以sys用户登陆数据库查询死锁
SQL> select username,lockwait,status,machine,program from v$session where sid in (select session_id from v$locked_object);
USERNAME LOCKWAIT STATUS ------------------------------ ---------------- -------- MACHINE ---------------------------------------------------------------- PROGRAM ------------------------------------------------ icdb JDBC Thin Client
ICUSER 000000038A37C0C8 ACTIVE icdb JDBC Thin Client
说明数据库有死锁
然后使用一下语句查找被死锁的语句
SQL> select sql_text from v$sql where hash_value in (select sql_hash_value from v$session where sid in (select session_id from v$locked_object));
SQL_TEXT -------------------------------------------------------------------------------- update JC_KXX SET LJXF =NVL ( LJXF , 0 ) + :1 , YE =:2 WHERE KH =:3 update jc_kxx set zt='07' where kh='1000530330'
再使用以下语句查找被死锁的进程
SQL> SELECT s.username,l.OBJECT_ID,l.SESSION_ID,s.SERIAL#, l.ORACLE_USERNAME,l.OS_USER_NAME,l.PROCESS FROM V$LOCKED_OBJECT l,V$SESSION S WHERE l.SESSION_ID=S.SID;
USERNAME OBJECT_ID SESSION_ID SERIAL# ------------------------------ ---------- ---------- ---------- ORACLE_USERNAME OS_USER_NAME PROCESS ------------------------------ ------------------------------ ------------ ICUSER 30523 32 42463 ICUSER oracle
ICUSER 30523 28 25508 ICUSER oracle
ICUSER 30523 76 14781 ICUSER oracle
USERNAME OBJECT_ID SESSION_ID SERIAL# ------------------------------ ---------- ---------- ---------- ORACLE_USERNAME OS_USER_NAME PROCESS ------------------------------ ------------------------------ ------------ ICUSER 30523 24 37522 ICUSER oracle
使用一下语句把死锁的进程kill
alter system kill session ‘sid,serial#’; (其中sid=l.session_id)
如:SQL> alter system kill session '24,37522';
再次执行存储过程,错误没有了。语句执行成功!
|