死鎖的原理
當對於數據庫某個表的某一列做更新或刪除等操作,執行完畢後該條語句不提
交,另一條對於這一列數據做更新操作的語句在執行的時候就會處於等待狀態,
此時的現象是這條語句一直在執行,但一直沒有執行成功,也沒有報錯。
死鎖的定位方法
通過檢查數據庫表,能夠檢查出是哪一條語句被死鎖,產生死鎖的機器是哪一台。
1)用dba用戶執行以下語句
select username,lockwait,status,machine,program from v$session where sid in (select session_id from v$locked_object)
如果有輸出的結果,則說明有死鎖,且能看到死鎖的機器是哪一台。字段說明:
2)用dba用戶執行以下語句,可以查看到被死鎖的語句。
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))
死鎖的解決例子
死鎖在Oracle中處理時,會自動事務相關的DML語句撤銷。換句話說,就是Oracle對於死鎖 問題的處理時一個主動的過程,會主動切斷其中一個session的事務鎖。
先來看一個簡單的死鎖案例。
我們創建兩個表lock_test1,lock_test2,然後使用兩個session來說明。
session1:
首先在session1中先創建兩個表,lock_test1,lock_test2
n1@TEST11G> create table lock_test1 as select *from cat; Table created. n1@TEST11G> create table lock_test2 as select *from cat; Table created.
然後嘗試對lock_test1做delete操作。
n1@TEST11G> delete from lock_test1; 20 rows deleted.
session2:
然後切換到session2,對lock_test2做delete操作。
n1@TEST11G> delete from lock_test2; 21 rows deleted.
緊接著,在session1中對lock_test2做delete操作,這個時候出現阻塞的情況,一直沒有響應。
session1:
n1@TEST11G> delete from lock_test2;
我們在session2中,繼續對表Lock_test1做delete操作,這個時候會有短暫的停頓,就會發現session1中的事務被強行撤銷了。
session2:
n1@TEST11G> delete from lock_test1;
session1中的日志如下,可以看到這個時候session1中的事務被強行撤銷了。
n1@TEST11G> delete from lock_test2; delete from lock_test2 * ERROR at line 1: ORA-00060: deadlock detected while waiting for resource
這個問題可以簡單用下面的步驟來說明。
到此為止我們可以看到,死鎖產生的影響是很大的,當然,問題還不止於此,在多個表之間很可能存在死鎖現象,對於一個表,也有可能出現死鎖現象。
我們來簡單說明示例一下。
session1:
create table test as select *from user_tables; n1@TEST11G> delete from test where table_name='LOCK_TEST1'; 1 row deleted.
session2:
n1@TEST11G> DELETE FROM TEST WHERE TABLE_NAME='LOCK_TEST2'; 1 row deleted. session1: n1@TEST11G> DELETE FROM TEST WHERE TABLE_NAME='LOCK_TEST2';
session2:
n1@TEST11G> DELETE FROM TEST WHERE TABLE_NAME='LOCK_TEST1';
這個時候還是會出現一樣的死鎖問題,這個時候在對應的行上會有相應的鎖。在session2中會有短暫的停頓,然後把session1中的
給撤銷了,產生的日志如下:
DELETE FROM TEST WHERE TABLE_NAME='LOCK_TEST2' * ERROR at line 1: ORA-00060: deadlock detected while waiting for resource
可見死鎖的問題還是很容易產生的,在編程中處理多並發的處理時還是需要多多注意。