一、活鎖
如果事務t1封鎖了資料r,事務t2又請求封鎖r,於是t2等待。t3也請求封鎖r,當t1釋放了r上的封鎖之後系統首先批准了t3的請求,t2仍然等待。然後t4又請求封鎖r,當t3釋放了r上的封鎖之後系統又批准了t4的請求,...,t2有可能永遠等待,這就是活鎖的情形。
避免活鎖的簡單方法是採用先來先服務的策略。
二、死鎖
如果事務t1封鎖了資料r1,t2封鎖了資料r2,然後t1又請求封鎖r2,因t2已封鎖了r2,於是t1等待t2釋放r2上的鎖。接著t2又申請封鎖r1,因t1已封鎖了r1,t2也只能等待t1釋放r1上的鎖。這樣就出現了t1在等待t2,而t2又在等待t1的局面,t1和t2兩個事務永遠不能結束,形成死鎖。
1. 死鎖的預防
在資料庫中,產生死鎖的原因是兩個或多個事務都已封鎖了一些資料物件,然後又都請求對已為其他事務封鎖的資料物件加鎖,從而出現死等待。防止死鎖的發生其實就是要破壞產生死鎖的條件。預防死鎖通常有兩種方法:
① 一次封鎖法
一次封鎖法要求每個事務必須一次將所有要使用的資料全部加鎖,否則就不能繼續執行。
一次封鎖法雖然可以有效地防止死鎖的發生,但也存在問題,一次就將以後要用到的全部資料加鎖,勢必擴大了封鎖的範圍,從而降低了系統的併發度。
② 順序封鎖法
順序封鎖法是預先對資料物件規定乙個封鎖順序,所有事務都按這個順序實行封鎖。
順序封鎖法可以有效地防止死鎖,但也同樣存在問題。事務的封鎖請求可以隨著事務的執行而動態地決定,很難事先確定每乙個事務要封鎖哪些物件,因此也就很難按規定的順序去施加封鎖。
可見,在作業系統中廣為採用的預防死鎖的策略並不很適合資料庫的特點,因此dbms在解決死鎖的問題上普遍採用的是診斷並解除死鎖的方法。
2. 死鎖的診斷與解除
① 超時法
如果乙個事務的等待時間超過了規定的時限,就認為發生了死鎖。超時法實現簡單,但其不足也很明顯。一是有可能誤判死鎖,事務因為其他原因使等待時間超過時限,系統會誤認為發生了死鎖。二是時限若設定得太長,死鎖發生後不能及時發現。
② 等待圖法
事務等待圖是乙個有向圖g=(t,u)。 t為結點的集合,每個結點表示正執行的事務;u為邊的集合,每條邊表示事務等待的情況。若t1等待t2,則t1、t2之間劃一條有向邊,從t1指向t2。事務等待圖動態地反映了所有事務的等待情況。併發控制子系統周期性地(比如每隔1分鐘)檢測事務等待圖,如果發現圖中存在迴路,則表示系統中出現了死鎖。
dbms的併發控制子系統一旦檢測到系統中存在死鎖,就要設法解除。通常採用的方法是選擇乙個處理死鎖代價最小的事務,將其撤消,釋放此事務持有的所有的鎖,使其它事務得以繼續執行下去。當然,對撤消的事務所執行的資料修改操作必須加以恢復。
銀行演算法
避免死鎖演算法中最有代表性的演算法是dijkstra e.w 於2023年提出的銀行家演算法:
該演算法需要檢查申請者對資源的最大需求量,如果系統現存的各類資源可以滿足申請者的請求,就滿足申請者的請求。
這樣申請者就可很快完成其計算,然後釋放它占用的資源,從而保證了系統中的所有程序都能完成,所以可避免死鎖的發生。
資料庫死鎖導致站點訪問故障解決方案
前段時間完成了乙個專案,但是現在該 訪問不了,真是鬱悶,主機重啟之後,執行正常,狗 google 也放了,csdn 也帖了,沒有解決,苦惱,後來發現是資料庫死鎖造成的問題。通過這個問題,我對資料庫思索也小小研究了一下,寫一點相關知識。死鎖原因 提取查詢資料相應資料,修改stat表,都是修改同一條資料...
資料庫亂碼解決方案
oracle 資料庫亂碼解決方案 你插入資料的時候,用 轉變字串的亂碼函式 param str return public string getstr string str catch exception e 向bean裡面賦值 public void setaction string action...
資料庫亂碼解決方案
mysql會出現中文亂碼的原因不外乎下列幾點 1.server本身設定問題,例如還停留在latin1 2.table的語系設定問題 包含character與collation 3.客戶端程式 例如php 的連線語系設定問題 強烈建議使用utf8 utf8可以相容世界上所有字元 一 避免建立資料庫及表...