例項分析資料庫死鎖的產生

2021-06-13 11:39:38 字數 1875 閱讀 1402

近日由於系統操作過程中會提示「事務(程序 id 54)與另乙個程序被死鎖在 鎖 資源上,並且已被選作死鎖犧牲品。請重新執行該事務。」

以前也出現過,但是無從下手,不知道該從**下手。朱總提示應該以出錯這條語句訪問到的表為中心查詢所有跟此表有關的sql語句,看有沒有可能造成死鎖。其實聽到這個提示,我腦子裡也是懵的。後來一看被犧牲的這條sql語句有三個表,而且是使用最頻繁的三個表,如果按朱總的想法那工作量有多大啊?再加上我對資料庫死鎖的一些細節還有點不清楚,這不是大海撈針嘛?

第二天我想了個辦法,首先重現這種死鎖,然後通過資料庫找到造成死鎖的前後sql,這樣範圍就小多了(說不准還能悟透死鎖的細節,當然這個是事前沒有想到的)。

說做就做,第一步就是重現死鎖,正好很久以前為測試這個系統的併發寫了乙個機械人,能模仿多個客戶端做常規操作。但是有些日子沒更新了,修改了大概2個小時,終於跑起來了,還不錯,能用。18個機械人做常規操作,我自己在客戶端做非常規操作,客戶端一停頓下來,馬上執行exec sp_who_lock。

54被86阻塞update sale_object set

objstateid=@objstateid

71、76、86、101被54阻塞select * from sale_objstate, sale_object, sale_subsvc

60、66被71阻塞update sale_object set

objstateid=@objstateid

通過了解「獨佔鎖x」 「共享鎖s」的含意總結如下:「」

-- select在readcommitted事務中加共享鎖,在repeatableread事務中加排它鎖;

-- insert、update、delete過程中始終應用排它鎖;

-- update必須等待select事務釋放共享鎖轉為排它鎖後才能執行;

-- 若事務t對資料物件a加上s鎖,則其它事務只能再對a加s鎖,而不能加x鎖,直到t釋放a上的s鎖  

-- 86號程序readcommitted

86 insert sale_objstate 得到 sale_objstate 獨佔鎖

86 select sale_objstate 保持獨佔鎖

86 update 需要 sale_object 獨佔鎖

-- 54號程序repeatableread

54 select * from sale_subsvc, sale_object, sale_objstate

依次得到sale_subsvc, sale_object的獨佔鎖,需要sale_objstate獨佔鎖但是被86佔了,得不到(這裡根據sql中的from語句依次得到表的鎖是我自己悟到的,因為作為程式不可能給三個表同時加鎖,必然是乙個乙個加的鎖,so……)

-- 71號程序與86號程序的過程是一樣的(此處省略)

由於54號程序中使用的是級別比較高階的事務,這也是造成死鎖最關鍵的一點。

解決辦法:

1.如果程式中54程序的查詢沒有必要使用repeatableread事務,那麼就將其修改為readcommitted事務。

2.如果程式中必須使用repeatableread事務,那麼就必須通過調換sql語句select * from sale_subsvc, sale_object, sale_objstate中sale_object和sale_objstate的順序來達到目的。但是這個調換也是有風險的,因為你不清楚是否還有其它位置和此處產生死鎖。這個解決方案比較複雜,不好從理論上進行細緻地討論。

此文的目的是讓讀者理解資料庫死鎖產生的一些細節,如果有什麼描述得不清楚的地方請指出,我一定答覆。

由於本人的水平是菜鳥級的,文中有理解得不對的地方歡迎指正!

資料庫死鎖分析與解決

一 死鎖的表現 1 錯誤資訊是 事務 程序 id 與另乙個程序被死鎖在 鎖 資源上,並且已被選作死鎖犧牲品。請重新執行該事務。2 錯誤資訊是 事務 程序 id 與另乙個程序被死鎖在 鎖 通訊緩衝區 資源上,並且已被選作死鎖犧牲品。請重新執行該事務。二 死鎖的原因 1 由於多使用者 多工的併發性和事務...

資料庫死鎖

1.死鎖的概念 死鎖是程序死鎖的簡稱,是由dijkstra於1965年研究銀行家演算法時首先提出來的。它是計算機作業系統乃至併發程式設計中最難處理的問題之一。實際上,死鎖問題不僅在計算機系統中存在,在我們日常生活中它也廣泛存在。我們先看看這樣乙個生活中的例子 在一條河上有一座橋,橋面較窄,只能容納一...

資料庫死鎖

資料庫在進行insert,update,delete這些更新操作的時候為了保證資料一致性都會使用排他鎖。乙個事務裡進行update操作,在事務結束之前 commit or rollback 排他鎖不會被釋放。因此在乙個事務裡update多條資料的時候執行順序就尤為重要,兩個併發事務中更新操作的執行順...