国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數(shù)據(jù)庫 > MySQL > 正文

詳解MySQL中的死鎖情況以及對死鎖的處理方法

2024-07-24 13:08:46
字體:
供稿:網(wǎng)友
這篇文章主要介紹了詳解MySQL中的死鎖情況以及對死鎖的處理方法,文中主要討論InnoDB存儲引擎中的死鎖情況,需要的朋友可以參考下
 

當多個事務同時持有和請求同一資源上的鎖而產(chǎn)生循環(huán)依賴的時候就產(chǎn)生了死鎖。死鎖發(fā)生在事務試圖以不同的順序鎖定資源。以StockPrice表上的兩個事務為例:

事務1

START TRANSACTION;UPDATE StockPrice SET close = 45.50 WHERE stock_id = 4 and date = '2002-05-01';UPDATE StockPrice SET close = 19.80 WHERE stock_id = 3 and date = '2002-05-02';COMMIT;

事務 #2

START TRANSACTION;UPDATE StockPrice SET high = 20.12 WHERE stock_id = 3 and date = '2002-05-02';UPDATE StockPrice SET;COMMIT;

如果不走運的話,每個事務都可以執(zhí)行完第一個語句,并在過程中鎖住資源。然后每個事務都試圖去執(zhí)行第二行語句,當時卻發(fā)現(xiàn)它被鎖住了。兩個事務將永遠的等待對方完成,除非有其他原因打斷死鎖。

為了解決這個問題,數(shù)據(jù)庫實現(xiàn)了各種死鎖探查和超時機制。像InnoDB這樣復雜的存儲引擎會提示循環(huán)依賴并且立即返回錯誤。否則死鎖將會導致查詢非常緩慢。其他一些不好的做法是等待超時后放棄。當前InnoDB處理死鎖的方式是回滾持有最少排他行級鎖的事務。(幾乎最簡單的回滾的參考指標)

鎖的行為是順序是存儲引擎決定的。因此,一些存儲引擎可能會在特定的操作順序下發(fā)生死鎖,其他的可能沒有。死鎖有兩種:一些是因為實際數(shù)據(jù)沖突而無法避免,一些是因為存儲引擎的工作方式產(chǎn)生。

只有部分或者完全回滾其中的一個事務才可能打破死鎖。死鎖是事務系統(tǒng)中客觀存在的事實,你的應該在設計上必須應該考慮處理死鎖。一些業(yè)務系統(tǒng)可以從頭重試事務。

如何處理死鎖
死鎖是事務型數(shù)據(jù)庫典型的問題,但是除非它們頻繁出現(xiàn)以至于你更本不能運行某個事務,它們一般是不危險的。正常地,你必須編寫你的應用程序使得它們總是準備如果因為死鎖而 回滾一個事務就重新發(fā)出一個事務。

InnoDB使用自動行級鎖定。即使在只插入或刪除單個行的事務的情況下,你可以遇到死鎖。這是因為這些操作不是真正的“極小的”,它們自動對插入或刪除的行的(可能是數(shù)個)索引記錄設置鎖定。

你可以用下列技術對付死鎖減少它們發(fā)生的可能性:

用Use SHOW INNODB STATUS來確定最后一個死鎖的原因。這樣可以幫助你調(diào)節(jié)應用程序來避免死鎖。

總是準備著重新發(fā)出事務,如果它因為死鎖而失敗了。死鎖不危險,再試一次。

經(jīng)常提交你的事務。小事務更少地傾向于沖突。

如果你正使用鎖定讀,(SELECT ... FOR UPDATE或 ... LOCK IN SHARE MODE),試著用更低的隔離級別,比如READ COMMITTED。

以固定的順序訪問你的表和行。則事務形成良好定義的查詢并且沒有死鎖。

添加精心選定的索引到你的表。則你的查詢需要掃描更少的索引記錄并且因此設置更少的鎖定。使用EXPLAIN SELECT來確定對于你的查詢,MySQL認為哪個索引是最適當?shù)摹?/p>

使用更少的鎖定。如果你可以接受允許一個SELECT從一個舊的快照返回數(shù)據(jù),不要給它添加FOR UPDATE或LOCK IN SHARE MODE子句。這里使用READ COMMITTED隔離級別是比較好的,因為每個在同一事務里的持續(xù)讀從它自己新鮮的快照里讀取。

如果沒有別的有幫助的了,用表級鎖定系列化你的事務。用LOCK TABLES對事務型表(如InnoDB)的正確方法是設置AUTOCOMMIT = 0 并且不調(diào)用UNLOCK TABLES直到你明確地提交了事務。例如,如果你需要寫表t1并從表t讀,你可以按如下做:

SET AUTOCOMMIT=0;LOCK TABLES t1 WRITE, t2 READ, ...;[do something with tables t1 and t2 here];COMMIT;UNLOCK TABLES;

表級鎖定使得你的事務很好地排隊,并且死鎖被避免了。

領一個系列化事務的方法是創(chuàng)建一個輔助的“semaphore” 表,它只包含一個單行。讓每個事務在訪問其它表之前更新那個行。以這種方式,所有事務以序列的方式發(fā)生。注意,InnoDB即時死鎖檢測算法也能在這種情況下起租用,因為系列化鎖定是行級鎖定。超時方法,用MySQL表級鎖定,必須被用來解決死鎖。

在應用程序中使用LOCK TABLES命令,如果AUTOCOMMIT=1,MySQL不設定InnoDB表鎖定。



注:相關教程知識閱讀請移步到MYSQL教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 曲周县| 衡阳市| 依安县| 二连浩特市| 甘谷县| 富锦市| 南漳县| 同江市| 乌海市| 黔江区| 龙南县| 潍坊市| 吉木乃县| 昂仁县| 遂溪县| 泗阳县| 韶山市| 中超| 共和县| 桑日县| 四川省| 蓬溪县| 璧山县| 凤凰县| 和龙市| 深水埗区| 资讯 | 巴塘县| 关岭| 米泉市| 永平县| 定远县| 海口市| 大同县| 资溪县| 云和县| 班玛县| 大悟县| 寿宁县| 汝阳县| 中西区|