本篇內(nèi)容主要講解“Oracle中的死鎖怎么理解”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Oracle中的死鎖怎么理解”吧!
10年積累的網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有皇姑免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
死鎖Dead Lock
我們大家最早接觸死鎖這個(gè)概念可能是在操作系統(tǒng)課程中,說多個(gè)進(jìn)程(線程)對(duì)一個(gè)可共享的資源進(jìn)行請(qǐng)求的時(shí)候,可能出現(xiàn)死鎖。死鎖問題分為死鎖檢測(cè)、處理等多個(gè)子問題可以進(jìn)行討論。
其實(shí),死鎖問題絕不僅僅限制在操作系統(tǒng)乃至計(jì)算機(jī)科學(xué)領(lǐng)域。死鎖存在的兩個(gè)必要條件,一個(gè)是多任務(wù)工作的并發(fā),另一個(gè)是共享資源的獨(dú)占性需求。只要一個(gè)系統(tǒng)(廣義系統(tǒng))中存在這兩個(gè)前提,我們就認(rèn)為可能出現(xiàn)死鎖的情況。
死鎖描述的是一種狀態(tài)。當(dāng)兩個(gè)或兩個(gè)以上的任務(wù)單元在執(zhí)行過程中,因?yàn)檎?qǐng)求資源出現(xiàn)等待,因資源永遠(yuǎn)不能獲得而相互等待的狀態(tài)。如果沒有外力的作用,死鎖狀態(tài)是會(huì)一直持續(xù)下去。死鎖是伴隨著多任務(wù)、并行操作產(chǎn)生的,在單任務(wù)情況下,一個(gè)任務(wù)單元可以使用并且獨(dú)占所有資源,不存在資源等待的情況,所以也沒有死鎖的情況。在進(jìn)入多任務(wù)系統(tǒng)環(huán)境下,多個(gè)任務(wù)之間存在資源共享和獨(dú)占的需求,才可能出現(xiàn)死鎖。
死鎖最簡(jiǎn)單的例子:任務(wù)A,B,資源1,2。任務(wù)A獨(dú)占了資源1,任務(wù)B獨(dú)占了資源2。此時(shí),任務(wù)A要資源2,向任務(wù)B提出請(qǐng)求并等待。任務(wù)B要求資源1,并且也等待。AB兩者均不釋放所占有的資源,就造成了死鎖。
Oracle中的死鎖
Oracle是目前商業(yè)數(shù)據(jù)庫(kù)市場(chǎng)上表現(xiàn)最優(yōu)秀的并發(fā)數(shù)據(jù)庫(kù)系統(tǒng),同樣存在死鎖的威脅。存在并發(fā)、存在資源獨(dú)占,就有鎖lock或者類似鎖概念的機(jī)制。Oracle提供了多種類型鎖和多種鎖的機(jī)制,包括共享鎖和獨(dú)占鎖。并且,在進(jìn)行各類型操作的時(shí)候,自動(dòng)的對(duì)對(duì)象進(jìn)行加鎖解鎖,以及鎖升級(jí)操作,最大可能的保證數(shù)據(jù)完整性。
那么,如果出現(xiàn)死鎖,Oracle會(huì)如何處理呢?
Oracle的鎖機(jī)制是建立在行鎖一級(jí),在插入、更新行一級(jí)信息的時(shí)候,會(huì)加入獨(dú)占鎖內(nèi)容。那么,我們嘗試模擬下出現(xiàn)死鎖的狀態(tài)。兩個(gè)session分別更新兩條記錄,在一個(gè)事務(wù)里再嘗試更新對(duì)方記錄,那么可以引發(fā)死鎖。
實(shí)驗(yàn)環(huán)境準(zhǔn)備:
SQL> desc t;
Name Type Nullable Default Comments
---- ------------ -------- ------- --------
ID NUMBER
COMM VARCHAR2(10) Y
SQL> select * from t where rownum<3;
ID COMM
---------- ----------
1 Tst1
2 Tst2
兩個(gè)session,分別針對(duì)id=1,2兩條記錄做文章。
//Session1
SQL> select sid from v$mystat where rownum<2;
SID
----------
152
SQL> update t set comm='Tst1' where id=1;
1 row updated
//Session2
SQL> select sid from v$mystat where rownum<2;
SID
----------
150
SQL> update t set comm='Tst2' where id=2;
1 row updated
此時(shí),鎖的狀態(tài)為:
SQL> select * from v$lock where sid in (150,152);
ADDR KADDR SID TYPE ID1 ID2 LMODE REQUEST
-------- -------- ---------- ---- ---------- ---------- ---------- ----------
333415A4 333415BC 152 TM 54599 0 3 0
33341668 33341680 150 TM 54599 0 3 0
3338A42C 3338A548 150 TX 393251 795 6 0
333B8954 333B8A70 152 TX 327686 779 6 0
此時(shí),我們看到了在兩個(gè)session中,分別使用了行鎖,獨(dú)占(LMODE=6)鎖住了兩行。下面繼續(xù)相互請(qǐng)求。
//session1中,嘗試更新id=2的記錄
SQL> update t set comm='Tst2' where id=2;
Session1(SID=152)被hange住。
//鎖狀態(tài)
SQL> select * from v$lock where sid in (150,152);
ADDR KADDR SID TYPE ID1 ID2 LMODE REQUEST
-------- -------- ---------- ---- ---------- ---------- ---------- ----------
33834398 338343AC 152 TX 393251 795 0 6
333415A4 333415BC 152 TM 54599 0 3 0
33341668 33341680 150 TM 54599 0 3 0
3338A42C 3338A548 150 TX 393251 795 6 0
333B8954 333B8A70 152 TX 327686 779 6 0
說明:在Oracle中,hange表示session正在等待資源被釋放,表現(xiàn)就是停住操作,不斷的輪詢資源。
Session2請(qǐng)求更新:
//session2(SID=150)
SQL> update t set comm='Tst1' where id=1;
注意:此時(shí),應(yīng)當(dāng)出現(xiàn)死鎖狀態(tài),而在系統(tǒng)中,也出現(xiàn)了一瞬間的兩個(gè)session互相hange的狀態(tài);
此時(shí),session2繼續(xù)被hange住,原先的session1退出,如下狀態(tài):
//session1(SID=152)
SQL> update t set comm='Tst2' where id=2;
update t set comm='Tst2' where id=2
ORA-00060:等待資源時(shí)檢測(cè)到死鎖
結(jié)果是:Oracle在兩個(gè)出現(xiàn)死鎖的session中,隨機(jī)尋找了一個(gè)session,駁回了其被hange住的請(qǐng)求,維持另一方session的hange狀態(tài)。
注意:Oracle此處的處理:只是駁回了一方的請(qǐng)求,并沒有回滾該請(qǐng)求,也沒有將另一方的hange狀態(tài)解除。
思考:顯然,這個(gè)過程中是Oracle內(nèi)部的防護(hù)機(jī)制起了作用,防止了系統(tǒng)中死鎖的發(fā)生。在Oracle中,存在某種輪詢的機(jī)制,隨時(shí)檢查系統(tǒng)中出現(xiàn)的多會(huì)話被hange住的情況,一旦發(fā)生,就將一個(gè)session被hange住的請(qǐng)求退回,拋出00060錯(cuò)誤。
在兩個(gè)session互鎖的情況下,Oracle死鎖檢測(cè)程序可以起作用。那么,如果死鎖結(jié)構(gòu)復(fù)雜的時(shí)候,是不是Oracle的檢測(cè)機(jī)制會(huì)失效。筆者使用4-5個(gè)session進(jìn)行檢查,雖然檢測(cè)起效的時(shí)間有長(zhǎng)有短,但最后都是將死鎖的狀態(tài)加以解除。
有一點(diǎn)需要注意,Oracle解決死鎖的方式只是將請(qǐng)求拒絕,并不是將事務(wù)回滾。所以,在解決死鎖之后,其他被hange住的session依然還是被hange住。所以,從應(yīng)用程序和PL/SQL的角度,如果接受到了60錯(cuò)誤,應(yīng)該做的工作就是回滾當(dāng)前事務(wù),解決整體的資源爭(zhēng)用現(xiàn)象。
Oracle死鎖發(fā)生
那么,Oracle中死鎖發(fā)生的幾率是不是那么高呢?答案是否定的。這個(gè)是由Oracle鎖的特性所決定的。
1、 Oracle對(duì)查詢不加鎖。Oracle本身支持多版本一致讀,如果當(dāng)前的數(shù)據(jù)塊正在被修改(獨(dú)占)而并未提交,Oracle會(huì)根據(jù)SCN查找日志和Undo空間,找到合適SCN的版本返回結(jié)果。所以,在查詢的時(shí)候,是不需要加鎖的。
2、 Oracle數(shù)據(jù)操作使用行級(jí)鎖(本質(zhì)上是事務(wù)鎖),實(shí)現(xiàn)最小粒度的獨(dú)占范圍。Oracle在DML的時(shí)候,只會(huì)對(duì)操作的行進(jìn)行獨(dú)占鎖定,而不是過大的數(shù)據(jù)單元(如頁page)。這樣,就保證了不會(huì)引起過多的獨(dú)占資源。
同時(shí),Oracle本身也提供了死鎖監(jiān)視程序功能,能及時(shí)發(fā)現(xiàn)死鎖狀態(tài),并自動(dòng)的進(jìn)行解鎖。在這些機(jī)制下,Oracle認(rèn)為死鎖發(fā)生的概率很低(起碼自身不會(huì)引起死鎖)。只有一種情況會(huì)引發(fā)死鎖,就是開發(fā)人員手工提高加鎖的級(jí)別。
Oracle對(duì)于SQL的拓展中,有一部分是顯示對(duì)象加鎖。從lock table XXX到select XXX for update。這些操作都會(huì)引起對(duì)對(duì)象鎖級(jí)別的提升,這些都可能引發(fā)死鎖的發(fā)生。
到此,相信大家對(duì)“Oracle中的死鎖怎么理解”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
新聞名稱:Oracle中的死鎖怎么理解
標(biāo)題網(wǎng)址:http://newbst.com/article22/jhcgjc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供面包屑導(dǎo)航、用戶體驗(yàn)、網(wǎng)站收錄、網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)公司、Google
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)