死鎖的原理
當(dāng)對(duì)于數(shù)據(jù)庫(kù)某個(gè)表的某一列做更新或刪除等操作,執(zhí)行完畢后該條語(yǔ)句不提
交,另一條對(duì)于這一列數(shù)據(jù)做更新操作的語(yǔ)句在執(zhí)行的時(shí)候就會(huì)處于等待狀態(tài),
此時(shí)的現(xiàn)象是這條語(yǔ)句一直在執(zhí)行,但一直沒(méi)有執(zhí)行成功,也沒(méi)有報(bào)錯(cuò)。
死鎖的定位方法
通過(guò)檢查數(shù)據(jù)庫(kù)表,能夠檢查出是哪一條語(yǔ)句被死鎖,產(chǎn)生死鎖的機(jī)器是哪一臺(tái)。
1)用dba用戶執(zhí)行以下語(yǔ)句
select username,lockwait,status,machine,program from v$session where sid in
(select session_id from v$locked_object)
如果有輸出的結(jié)果,則說(shuō)明有死鎖,且能看到死鎖的機(jī)器是哪一臺(tái)。字段說(shuō)明:
- Username:死鎖語(yǔ)句所用的數(shù)據(jù)庫(kù)用戶;
- Lockwait:死鎖的狀態(tài),如果有內(nèi)容表示被死鎖。
- Status: 狀態(tài),active表示被死鎖
- Machine: 死鎖語(yǔ)句所在的機(jī)器。
- Program: 產(chǎn)生死鎖的語(yǔ)句主要來(lái)自哪個(gè)應(yīng)用程序。
2)用dba用戶執(zhí)行以下語(yǔ)句,可以查看到被死鎖的語(yǔ)句。
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中處理時(shí),會(huì)自動(dòng)事務(wù)相關(guān)的DML語(yǔ)句撤銷。換句話說(shuō),就是Oracle對(duì)于死鎖 問(wèn)題的處理時(shí)一個(gè)主動(dòng)的過(guò)程,會(huì)主動(dòng)切斷其中一個(gè)session的事務(wù)鎖。
先來(lái)看一個(gè)簡(jiǎn)單的死鎖案例。
我們創(chuàng)建兩個(gè)表lock_test1,lock_test2,然后使用兩個(gè)session來(lái)說(shuō)明。
session1:
首先在session1中先創(chuàng)建兩個(gè)表,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.
然后嘗試對(duì)lock_test1做delete操作。
n1@TEST11G> delete from lock_test1;
20 rows deleted.
session2:
然后切換到session2,對(duì)lock_test2做delete操作。
n1@TEST11G> delete from lock_test2;
21 rows deleted.
緊接著,在session1中對(duì)lock_test2做delete操作,這個(gè)時(shí)候出現(xiàn)阻塞的情況,一直沒(méi)有響應(yīng)。
session1:
n1@TEST11G> delete from lock_test2;
我們?cè)趕ession2中,繼續(xù)對(duì)表Lock_test1做delete操作,這個(gè)時(shí)候會(huì)有短暫的停頓,就會(huì)發(fā)現(xiàn)session1中的事務(wù)被強(qiáng)行撤銷了。
session2:
n1@TEST11G> delete from lock_test1;
session1中的日志如下,可以看到這個(gè)時(shí)候session1中的事務(wù)被強(qiáng)行撤銷了。
n1@TEST11G> delete from lock_test2;
delete from lock_test2
*
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource
這個(gè)問(wèn)題可以簡(jiǎn)單用下面的步驟來(lái)說(shuō)明。
- Session a table1
- Session b table2
- Session a table 2
- Session b table1
到此為止我們可以看到,死鎖產(chǎn)生的影響是很大的,當(dāng)然,問(wèn)題還不止于此,在多個(gè)表之間很可能存在死鎖現(xiàn)象,對(duì)于一個(gè)表,也有可能出現(xiàn)死鎖現(xiàn)象。
我們來(lái)簡(jiǎn)單說(shuō)明示例一下。
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';
這個(gè)時(shí)候還是會(huì)出現(xiàn)一樣的死鎖問(wèn)題,這個(gè)時(shí)候在對(duì)應(yīng)的行上會(huì)有相應(yīng)的鎖。在session2中會(huì)有短暫的停頓,然后把session1中的
給撤銷了,產(chǎn)生的日志如下:
DELETE FROM TEST WHERE TABLE_NAME='LOCK_TEST2'
*
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource
可見(jiàn)死鎖的問(wèn)題還是很容易產(chǎn)生的,在編程中處理多并發(fā)的處理時(shí)還是需要多多注意。
您可能感興趣的文章:- Oracle 查詢死鎖并解鎖的終極處理方法
- 講解Oracle數(shù)據(jù)庫(kù)中結(jié)束死鎖進(jìn)程的一般方法
- Oracle數(shù)據(jù)表中的死鎖情況解決方法
- oracle 會(huì)話 死鎖 執(zhí)行sql 執(zhí)行job的方法
- Oracle刪除死鎖進(jìn)程的方法
- Oracle對(duì)于死鎖的處理方法
- Oracle外鍵不加索引引起死鎖示例
- Oracle 死鎖的檢測(cè)查詢及處理