批量解決oracle鎖等待的方法

season0891發表於2013-12-23
批量解決oracle鎖等待的方法
 
據我所知,oracle 10g之後的oracle版本不會因為使用者的操作原因,造成死鎖。
 
大家通常會遇到這種現象,在自己web專案首頁使用使用者名稱,密碼登陸系統時,始終停留在本頁面,無法進入系統,或是在執行某些操作後,系統一直處在等待狀態,不出結果,後臺也無任何錯誤提醒。此時,很大的可能就是資料庫鎖等待,所要查詢的包含使用者名稱和密碼的表或是使用者正操作的表正在被佔用造成的。
 
鎖等待的現象:程式在執行的過程中,點選確定或儲存按鈕,程式沒有響應,也沒有出現報錯。
 
網上有很多人把這種現象稱為死鎖,我認為是不合理的。此時的oracle並未發生任何死鎖現象,只是它一直在等待使用者前一個操作的提交。
 
產生鎖等待的原因:當對於資料庫某個表的某一列做更新或刪除等操作,執行完畢後該條語句不提交,另一條對於這一列資料做更新操作的語句在執行的時候就會處於等待狀態,此時的現象是這條語句一直在執行,但一直沒有執行成功,也沒有報錯。
 
鎖等待定位方法:
 
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程式碼  
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;  
 
以上兩種方法皆可以,不過查詢出來的屬性不同,可以根據個人需要選擇。其中有一種方法速度較快,但我忘記是哪一種了,您若遇到資料庫出現和鎖等待相符的現象,可以用這兩種方法查詢試一下,若得到結果,則說明確實發生鎖等待現象了。
 
單個解決鎖等待的方法:
 
Sql程式碼  
alter system kill session 'sid, serial#'  
 
其中的sid和serial可以通過上面鎖等待定位方法的第二個方法得到,sid對應SESSION_ID,serial#對應SERIAL#。例如:
 
Sql程式碼  
alter system kill session '130,2';  
 
我通常會遇到上千個鎖,實在沒辦法一個一個的kill掉了,所以我通常使用下述批量解鎖方法。
 
批量解鎖方法:
注:此方法應在plsql中執行
 
Sql程式碼  
declare cursor mycur is  
select b.sid,b.serial#  
  from v$locked_object a,v$session b  
  where a.session_id = b.sid group by b.sid,b.serial#;  
  
begin  
  for cur in mycur  
    loop    
     execute immediate ( 'alter system  kill session  '''||cur.sid || ','|| cur.SERIAL# ||''' ');  
     end loop;  
end;  
 
若讀者在使用中出現問題,可能是中英文字元轉換造成的,請讀者注意。

http://www.2cto.com/database/201304/200815.html

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/90618/viewspace-1064027/,如需轉載,請註明出處,否則將追究法律責任。

相關文章