造成死鎖的原因就是多個線程或進程對同一個資源的爭搶或相互依賴。這里列舉一個對同一個資源的爭搶造成死鎖的實例。
十余年的東昌網站建設經驗,針對設計、前端、開發、售后、文案、推廣等六對一服務,響應快,48小時及時工作處理。全網營銷推廣的優勢是能夠根據用戶設備顯示端的尺寸不同,自動調整東昌建站的顯示方式,使網站能夠適用不同顯示終端,在瀏覽器中調整網站的寬度,無論在任何一種瀏覽器上瀏覽網站,都能展現優雅布局與設計,從而大程度地提升瀏覽體驗。創新互聯公司從事“東昌網站設計”,“東昌網站推廣”以來,每個客戶項目都認真落實執行。
CREATE TABLE testLock( ID NUMBER,
test VARCHAR (100) )
COMMIT
INSERT INTO testLock VALUES (1, 'test1' );
INSERT INTO testLock VALUES (2, 'test2' );
COMMIT ;
SELECT * FROM testLock
ID TEST
---------- ----------------------------------
1 test1
2 test2
死鎖現象的重現:
1. 在sql 窗口 執行:SELECT * FROM testLock FOR UPDATE; -- 加行級鎖 并對內容進行修改,不要提交
查看引起死鎖的語句:
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));
查出以下語句死鎖:
delete from testLock where ID = 1
死鎖的處理:
alter system kill session 'session_id,serial#';
alter system kill session '301,16405';
再查看一下死鎖,會發現已經沒有stauts為active的記錄了,
發生死鎖的語句已經被終止。
客戶的10.2.0.4 RAC for AIX環境頻繁出現ORA-60死鎖問題,導致應用程序無法順利執行。
經過一系列的診斷,發現最終問題是由于外鍵上沒有建立索引所致,由于程序在主子表上刪除數據,缺少索引導致行級鎖升級為表級鎖,最終導致大量的鎖等待和死鎖。
下面通過一個例子簡單模擬一下問題:
SQL> create table t_p (id number primary key, name varchar2(30));
Table created.
SQL> create table t_f (fid number, f_name varchar2(30), foreign key (fid) references t_p);
Table created.
SQL> insert into t_p values (1, 'a');
1 row created.
SQL> insert into t_f values (1, 'a');
1 row created.
SQL> insert into t_p values (2, 'b');
1 row created.
SQL> insert into t_f values (2, 'c');
1 row created.
SQL> commit;
Commit complete.
SQL> delete t_f where fid = 2;
1 row deleted.
這時在會話2同樣對子表進行刪除:
SQL2> delete t_f where fid = 1;
1 row deleted.
回到會話1執行主表的刪除:
SQL> delete t_p where id = 2;
會話被鎖,回到會話2執行主表的刪除:
SQL2> delete t_p where id = 1;
會話同樣被鎖,這時會話1的語句被回滾,出現ORA-60死鎖錯誤:
delete t_p where id = 2
*
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource
SQL> rollback;
Rollback complete.
將會話1操作回滾,會話2同樣回滾并建立外鍵列上的索引:
1 row deleted.
SQL2> rollback;
Rollback complete.
SQL2> create index ind_t_f_fid on t_f(fid);
Index created.
重復上面的步驟會話1刪除子表記錄:
SQL> delete t_f where fid = 2;
1 row deleted.
會話2刪除子表記錄:
SQL2> delete t_f where fid = 1;
1 row deleted.
會話1刪除主表記錄:
SQL> delete t_p where id = 2;
1 row deleted.
會話2刪除主表記錄:
SQL> delete t_p where id = 1;
1 row deleted.
所有的刪除操作都可以成功執行,關于兩種情況下鎖信息的不同這里就不深入分析了,重點就是在外鍵列上建立索引。
雖然有一些文章提到過,如果滿足某些情況,可以不在外鍵列上建立的索引,但是我的觀點一向是,既然創建了外鍵,就不要在乎再多一個索引,因為一個索引所增加的代價,與缺失這個索引所帶來的問題相比,是微不足道的。
網站標題:Oracle常見死鎖發生的原因以及解決方法
網頁URL:http://www.yijiale78.com/article26/gipijg.html
成都網站建設公司_創新互聯,為您提供關鍵詞優化、網站內鏈、、網站策劃、小程序開發、響應式網站
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯