簡介
每個使用關(guān)系型數(shù)據(jù)庫的程序都可能遇到數(shù)據(jù)死鎖或不可用的情況,而這些情況需要在代碼中編程來解決;本文主要介紹與數(shù)據(jù)庫事務(wù)死鎖等情況相關(guān)的重試邏輯概念,此外,還會探討如何避免死鎖等問題,文章以DB2(版本9)與Java為例進(jìn)行講解。
什么是數(shù)據(jù)庫鎖定與死鎖
鎖定(Locking)發(fā)生在當(dāng)一個事務(wù)獲得對某一資源的“鎖”時,這時,其他的事務(wù)就不能更改這個資源了,這種機(jī)制的存在是為了保證數(shù)據(jù)一致性;在設(shè)計(jì)與數(shù)據(jù)庫交互的程序時,必須處理鎖與資源不可用的情況。鎖定是個比較復(fù)雜的概念,仔細(xì)說起來可能又需要一大篇,所以在本文中,只把鎖定看作是一個臨時事件,這意味著如果一個資源被鎖定,它總會在以后某個時間被釋放。而死鎖發(fā)生在當(dāng)多個進(jìn)程訪問同一數(shù)據(jù)庫時,其中每個進(jìn)程擁有的鎖都是其他進(jìn)程所需的,由此造成每個進(jìn)程都無法繼續(xù)下去。
如何避免鎖
我們可利用事務(wù)型數(shù)據(jù)庫中的隔離級別機(jī)制來避免鎖的創(chuàng)建,正確地使用隔離級別可使程序處理更多的并發(fā)事件(如允許多個用戶訪問數(shù)據(jù)),還能預(yù)防像丟失修改(Lost Update)、讀“臟”數(shù)據(jù)(Dirty Read)、不可重復(fù)讀(Nonrepeatable Read)及“虛”(Phantom)等問題。
隔離級別 問題現(xiàn)象
丟失修改 讀“臟”數(shù)據(jù) 不可重復(fù)讀 “虛”
可重復(fù)讀取 No No No No
讀取穩(wěn)定性 No No No Yes
光標(biāo)穩(wěn)定性 No No Yes Yes
未提交的讀 No Yes Yes Yes
表DB2的隔離級別與其對應(yīng)的問題現(xiàn)象
在只讀模式中,就可以防止鎖定發(fā)生,而不用那些未提交只讀隔離級別的含糊語句。一條SQL語句當(dāng)使用了下列命令之一時,就應(yīng)該考慮只讀模式了:
1、JOIN
2、SELECT DISTINCT
3、GROUP BY
4、ORDER BY
5、UNION
6、UNION ALL
7、SELECT
8、FOR FETCH ONLY (FOR READ ONLY)
9、SELECT FROM
如果包含上述任一命令,可以說你的SQL語句有歧義性,因此,鎖可能就是造成其中資源問題的源頭。
每個使用關(guān)系型數(shù)據(jù)庫的程序都可能遇到數(shù)據(jù)死鎖或不可用的情況,而這些情況需要在代碼中編程來解決;本文主要介紹與數(shù)據(jù)庫事務(wù)死鎖等情況相關(guān)的重試邏輯概念,此外,還會探討如何避免死鎖等問題,文章以DB2(版本9)與Java為例進(jìn)行講解。
什么是數(shù)據(jù)庫鎖定與死鎖
鎖定(Locking)發(fā)生在當(dāng)一個事務(wù)獲得對某一資源的“鎖”時,這時,其他的事務(wù)就不能更改這個資源了,這種機(jī)制的存在是為了保證數(shù)據(jù)一致性;在設(shè)計(jì)與數(shù)據(jù)庫交互的程序時,必須處理鎖與資源不可用的情況。鎖定是個比較復(fù)雜的概念,仔細(xì)說起來可能又需要一大篇,所以在本文中,只把鎖定看作是一個臨時事件,這意味著如果一個資源被鎖定,它總會在以后某個時間被釋放。而死鎖發(fā)生在當(dāng)多個進(jìn)程訪問同一數(shù)據(jù)庫時,其中每個進(jìn)程擁有的鎖都是其他進(jìn)程所需的,由此造成每個進(jìn)程都無法繼續(xù)下去。
如何避免鎖
我們可利用事務(wù)型數(shù)據(jù)庫中的隔離級別機(jī)制來避免鎖的創(chuàng)建,正確地使用隔離級別可使程序處理更多的并發(fā)事件(如允許多個用戶訪問數(shù)據(jù)),還能預(yù)防像丟失修改(Lost Update)、讀“臟”數(shù)據(jù)(Dirty Read)、不可重復(fù)讀(Nonrepeatable Read)及“虛”(Phantom)等問題。
隔離級別 問題現(xiàn)象
丟失修改 讀“臟”數(shù)據(jù) 不可重復(fù)讀 “虛”
可重復(fù)讀取 No No No No
讀取穩(wěn)定性 No No No Yes
光標(biāo)穩(wěn)定性 No No Yes Yes
未提交的讀 No Yes Yes Yes
表DB2的隔離級別與其對應(yīng)的問題現(xiàn)象
在只讀模式中,就可以防止鎖定發(fā)生,而不用那些未提交只讀隔離級別的含糊語句。一條SQL語句當(dāng)使用了下列命令之一時,就應(yīng)該考慮只讀模式了:
1、JOIN
2、SELECT DISTINCT
3、GROUP BY
4、ORDER BY
5、UNION
6、UNION ALL
7、SELECT
8、FOR FETCH ONLY (FOR READ ONLY)
9、SELECT FROM
如果包含上述任一命令,可以說你的SQL語句有歧義性,因此,鎖可能就是造成其中資源問題的源頭。