新聞中心
在數(shù)據(jù)庫中,鎖是非常重要的機(jī)制。鎖的實(shí)現(xiàn)可以提供并發(fā)訪問時(shí)的數(shù)據(jù)完整性和一致性,確保多線程或多進(jìn)程同時(shí)操作數(shù)據(jù)庫時(shí),數(shù)據(jù)的正確性不會(huì)受到影響。而鎖隔離級別則是指數(shù)據(jù)庫為了滿足并發(fā)控制要求,而規(guī)定的不同事務(wù)之間的隔離等級。

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長期合作伙伴,公司提供的服務(wù)項(xiàng)目有:域名注冊、雅安服務(wù)器托管、營銷軟件、網(wǎng)站建設(shè)、豐南網(wǎng)站維護(hù)、網(wǎng)站推廣。
數(shù)據(jù)庫的事務(wù)并發(fā)控制是通過鎖的機(jī)制實(shí)現(xiàn)的,可分為悲觀鎖和樂觀鎖。在悲觀鎖機(jī)制下,數(shù)據(jù)的操作需要先獲得相應(yīng)的鎖,只要有一個(gè)事務(wù)持有鎖,其他的事務(wù)就必須等待,這個(gè)等待過程就是阻塞過程,所以悲觀鎖機(jī)制下,多個(gè)事務(wù)同時(shí)并發(fā)執(zhí)行時(shí),性能會(huì)受到很大的影響。而在樂觀鎖機(jī)制下,首先不會(huì)有阻塞過程,而是先對數(shù)據(jù)進(jìn)行操作,當(dāng)需要提交時(shí),才進(jìn)行數(shù)據(jù)的校驗(yàn),如果數(shù)據(jù)校驗(yàn)通過,則事務(wù)提交成功,否則進(jìn)行回滾。
不同的數(shù)據(jù)庫的鎖隔離級別定義略有區(qū)別,但大體可以分為以下四種(從低到高):
1. 讀未提交(Read Uncommitted):這是更低的隔離級別,該級別下,一個(gè)事務(wù)可以讀取另一個(gè)事務(wù)未提交的數(shù)據(jù),可能導(dǎo)致臟讀、不可重復(fù)讀和幻讀的問題。
2. 讀已提交(Read Committed):在該級別下,一個(gè)事務(wù)只能讀取已經(jīng)提交的數(shù)據(jù),避免了臟讀的問題,但同時(shí)可能導(dǎo)致不可重復(fù)讀和幻讀的問題,比如在一個(gè)事務(wù)更新時(shí),另一個(gè)事務(wù)讀取該數(shù)據(jù)時(shí),可能還未提交事務(wù)的更新,導(dǎo)致讀出的結(jié)果與該事務(wù)提交后讀取的結(jié)果不一致。
3. 可重復(fù)讀(Repeatable Read):該隔離級別下,一個(gè)事務(wù)可以多次讀取相同的數(shù)據(jù),保證了同一事務(wù)中,數(shù)據(jù)的可重復(fù)讀取性,但同時(shí)可能會(huì)導(dǎo)致幻讀的問題?;米x是指某一個(gè)事務(wù)(通常是insert)在讀到一組數(shù)據(jù)(比如某個(gè)范圍內(nèi)的所有記錄)后,在進(jìn)行修改時(shí),另一個(gè)事務(wù)(通常也是insert)在之前沒有出現(xiàn)的數(shù)據(jù)同時(shí)更新,在之一個(gè)事務(wù)再次查看數(shù)據(jù)時(shí),發(fā)現(xiàn)了之前沒有的數(shù)據(jù)。
4. 串行化(Serializable ):該級別下,所有的事務(wù)只能串行執(zhí)行,因此可以避免臟讀、不可重復(fù)讀和幻讀的問題。但同時(shí)也是效率更低的。
在實(shí)際使用中,我們應(yīng)該根據(jù)具體場景來選擇合適的鎖隔離級別。如果強(qiáng)一致性要求不是特別高,可以選擇Read Committed隔離級別,如果要求強(qiáng)一致性,則可以選擇Repeatable Read隔離級別;如果對性能要求非常高,Query-by-consistency (QBC) 也許更適合你。
數(shù)據(jù)庫鎖隔離級別的選擇需要根據(jù)應(yīng)用場景、性能、數(shù)據(jù)一致性等方面來綜合考慮。正確的選擇可以提高系統(tǒng)的并發(fā)性、可用性和性能,而錯(cuò)誤的選擇則可能導(dǎo)致各種問題和瓶頸。
相關(guān)問題拓展閱讀:
- 如何解除sql server數(shù)據(jù)庫數(shù)據(jù)被鎖定
- 如何處理SQL Server死鎖問題
如何解除sql server數(shù)據(jù)庫數(shù)據(jù)被鎖定
(1)
HOLDLOCK:
在該表上保持共享鎖,直到整個(gè)事務(wù)結(jié)束,而不是在語句執(zhí)行完立即釋放所添加的鎖。
(2)
NOLOCK:不添加共享鎖和排它鎖,當(dāng)這個(gè)選項(xiàng)生效后,可能讀到未提交讀的數(shù)據(jù)或“臟數(shù)據(jù)”,這個(gè)選項(xiàng)僅僅應(yīng)用于SELECT語句。
(3)
PAGLOCK:指定添加頁鎖(否則通??赡芴砑颖礞i)。
(4)
READCOMMITTED用與運(yùn)行在提交讀隔離畝改級別的事務(wù)相同的鎖語義執(zhí)行掃描。默認(rèn)情況下,SQL
Server
2023
在此隔離級別上操作。
(5)
READPAST:
跳過已經(jīng)加鎖的數(shù)據(jù)行,這個(gè)選項(xiàng)將使事務(wù)讀取數(shù)據(jù)時(shí)跳過那些已經(jīng)被其他事務(wù)鎖定的數(shù)據(jù)行,而不是阻塞直到其他事務(wù)釋放鎖,
READPAST僅僅應(yīng)用于READ
COMMITTED隔離性級別下事務(wù)操作中的SELECT語句操作。
(6)
READUNCOMMITTED:等同于NOLOCK。
(7)
REPEATABLEREAD:設(shè)置事務(wù)為可重復(fù)讀隔離性級別。
(8)
ROWLOCK:使用行級余耐沒鎖,而不使用粒度更粗的頁級鎖和表級鎖。
(9)
SERIALIZABLE:用與運(yùn)行在可串行讀隔離級別的事務(wù)相同的鎖語義執(zhí)行掃描。等同于
HOLDLOCK。
(10)
TABLOCK:指定使用表級鎖,而不是使用行級或頁面級的鎖,SQL
Server在該語句執(zhí)行完后釋放這個(gè)鎖,而如果同時(shí)指定了…(1)
HOLDLOCK:
在該表上保持共享鎖,直到整個(gè)事務(wù)結(jié)束,而不是在語句執(zhí)行完立即釋放所添加的鎖。
(2)
NOLOCK:不添加共享鎖和排它鎖,當(dāng)這個(gè)選項(xiàng)生效后,可能讀到未提交讀的數(shù)據(jù)或“臟數(shù)據(jù)”,這個(gè)選項(xiàng)僅僅應(yīng)用于SELECT語句。
(3)
PAGLOCK:指定添加頁鎖(否則通??赡芴砑颖礞i)。
(4)
READCOMMITTED用與運(yùn)行在提交讀隔離級別的事務(wù)相同的鎖語義執(zhí)行掃描。默認(rèn)情況下,SQL
Server
2023
在此隔離級別上操作。
(5)
READPAST:
跳過已經(jīng)加鎖的數(shù)據(jù)行,這個(gè)選項(xiàng)將使事務(wù)讀取數(shù)據(jù)時(shí)跳過那些已經(jīng)被其他事務(wù)鎖定的數(shù)據(jù)行,而不是阻塞直到其他事務(wù)釋放鎖,
READPAST僅僅應(yīng)用于READ
COMMITTED隔離性級別下事務(wù)操作中的SELECT語句操作。
(6)
READUNCOMMITTED:等同于NOLOCK。
(7)
REPEATABLEREAD:設(shè)置事務(wù)為可重復(fù)讀隔離性級別。
(8)
ROWLOCK:使用行級鎖,而不使用粒度更粗的頁級鎖和表級鎖。
(9)
SERIALIZABLE:用與運(yùn)行在可串行讀隔豎納離級別的事務(wù)相同的鎖語義執(zhí)行掃描。等同于
HOLDLOCK。
(10)
TABLOCK:指定使用表級鎖,而不是使用行級或頁面級的鎖,SQL
Server在該語句執(zhí)行完后釋放這個(gè)鎖,而如果同時(shí)指定了HOLDLOCK,該鎖一直保持到這個(gè)事務(wù)結(jié)束。
(11)
TABLOCKX:指定在表上使用排它鎖,這個(gè)鎖可以阻止其他事務(wù)讀或更新這個(gè)表的數(shù)據(jù),直到這個(gè)語句或整個(gè)事務(wù)結(jié)束。
(12)
UPDLOCK
:指定在
讀表中數(shù)據(jù)時(shí)設(shè)置更新
鎖(update
lock)而不是設(shè)置共享鎖,該鎖一直保持到這個(gè)語句或整個(gè)事務(wù)結(jié)束,使用UPDLOCK的作用是允許用戶先讀取數(shù)據(jù)(而且不阻塞其他用戶讀數(shù)據(jù)),并且保證在后來再更新數(shù)據(jù)時(shí),這一段時(shí)間內(nèi)這些數(shù)據(jù)沒有被其他用戶修改。
如何處理SQL Server死鎖問題
1)
預(yù)防死鎖。
這是一種較簡單和直觀的事先預(yù)防的方法。方法是通過設(shè)置某些限制條件,去破壞產(chǎn)生死鎖的四個(gè)必要條件中的一個(gè)或者幾個(gè),來預(yù)防發(fā)生死鎖。預(yù)防死鎖是一種較易實(shí)現(xiàn)的方法,已被廣泛使用。但是由于所施加的限制條件往往太嚴(yán)格,可能會(huì)導(dǎo)致系統(tǒng)資源利用率和系統(tǒng)吞吐量降低。
2)
避免死鎖。
該方法同樣是屬于事先預(yù)防的策略,但它并不須事先采取各種限制措施去破壞產(chǎn)生死鎖的的四個(gè)必要條件,而是在資源的動(dòng)態(tài)分配過程中,用某種方法去隱源防止系統(tǒng)進(jìn)入不安全狀態(tài),從而避免發(fā)生死鎖。
3)檢測死鎖。
這種方法并不須事先采取任何限制性措施,也不必檢查系統(tǒng)是否已經(jīng)進(jìn)入不安全區(qū),此方法允灶春態(tài)許系統(tǒng)在運(yùn)行過程中發(fā)生死鎖。但可通過系統(tǒng)所設(shè)置的檢測機(jī)構(gòu),及時(shí)地檢測出死鎖的發(fā)生,并精確地確定與死鎖有關(guān)的進(jìn)程和資源,然后采取適當(dāng)措施,從系統(tǒng)中將已發(fā)生的死鎖清除掉。
4)解除死鎖。
這是與檢測死鎖相配套的一種措施。當(dāng)檢測到系統(tǒng)中已發(fā)生死鎖時(shí),須將進(jìn)程從死鎖狀態(tài)中解脫出來。常用的實(shí)施方法是撤銷或掛起一些進(jìn)程,以便回收一些資源,再將這些資源分配給已處于阻塞狀態(tài)的進(jìn)程,使之轉(zhuǎn)為就緒狀態(tài),以繼續(xù)運(yùn)行。死鎖的檢測和解除措施,有可能使系統(tǒng)獲得較好的資源利用率和吞吐量,但在實(shí)現(xiàn)上難度也更大。
由上面4中處理死鎖的辦法看,其中檢測死鎖和解除死鎖是Lock
Monitor的事,作為DBA或數(shù)據(jù)庫開發(fā)人員,處理死鎖要放在預(yù)防和避免死鎖上。
預(yù)防死鎖
預(yù)防死鎖就是破壞四個(gè)必要條件中的某一個(gè)和幾個(gè),使其不能形成死鎖。有如下幾種辦法
1)破壞互斥條件
破壞互斥條件有比較嚴(yán)格的限制,在SQL
Server中,如果業(yè)務(wù)邏輯上允許臟讀,則可以通過將隔離等級改為未提交讀或使用索引提示。這樣使得讀取不用加S鎖,從而避免了和其它查詢所加的與S鎖不兼容的鎖互斥,進(jìn)而減少了死鎖出現(xiàn)的概率。
2)破壞請求和等待條件
這點(diǎn)由于事務(wù)存在原子性,是不可破壞的,因?yàn)榻馍鉀Q辦法是盡量的減少事務(wù)的長度,事務(wù)內(nèi)執(zhí)行的越快越好。這也可以減少死鎖出現(xiàn)的概率。
3)破壞不剝奪條件
由于事務(wù)的原子性和一致性,不剝奪條件同樣不可破壞。但我們可以通過增加資源和減少資源占用兩個(gè)角度來考慮。
增加資源:比如說通過建立非聚集索引,使得有了額外的資源,查詢很多時(shí)候就不再索要鎖基本表,轉(zhuǎn)而鎖非聚集索引,如果索引能夠“覆蓋(Cover)”查詢,那更好不過。因此索引Include列不僅僅減少書簽查找來提高性能,還能減少死鎖。增加資源還可以通過SQL
Server
2023之后的行版本控制進(jìn)行,但這種方式并不推薦,在此不再詳細(xì)討論。
減少資源占用:比如說查詢時(shí),能用select
col1,col2這種方式,就不要用select
*
.這有可能帶來不必要的書簽查找
死鎖,簡而言之,兩個(gè)或者多個(gè)trans,同時(shí)請求對方正在請求的某個(gè)對象,導(dǎo)致雙野物方互相等待。簡單的例子如下:
trans trans2
—–
1.IDBConnection.BeginTransaction 1.IDBConnection.BeginTransaction
2.update table A2.update table B
3.update table B3.update table A
4.IDBConnection.Commit 4.IDBConnection.Commit
那么,很容易看到,如果trans1和trans2,分別到達(dá)了step3,那么trans1會(huì)請求對于B的X鎖,trans2會(huì)請求對于A的X鎖,而二者的鎖在step2上已經(jīng)被對方分別持有了。由于得不到鎖,后面的Commit無法執(zhí)行,這樣雙方開始死鎖。
好,我們看一個(gè)簡單的例子,來解釋一下,應(yīng)該如何解決死鎖問題。
— Batch #1
CREATE DATABASE deadlocktest
GO
USE deadlocktest
SET NOCOUNT ON
DBCC TRACEON (1222, -1)
— 在SQL2023中,增加了一個(gè)新的dbcc參數(shù),就是1222,原來在2023下,我們知道,可以執(zhí)行dbcc
–traceon(1204,3605,-1)看到所有的死鎖信息。SqlServer 2023中,頌判液對于1204進(jìn)行了增強(qiáng),這就是1222。
GO
IF OBJECT_ID (‘t1’) IS NOT NULL DROP TABLE t1
IF OBJECT_ID (‘p1’) IS NOT NULL DROP PROC p1
IF OBJECT_ID (‘p2’) IS NOT NULL DROP PROC p2
GO
CREATE TABLE t1 (c1 int, c2 int, c3 int, c4 char(5000))
GO
DECLARE @x int
SET @x = 1
WHILE (@x = AND . = AND … +(1)) ORDERED FORWARD)
哦,對于clustered index的需求沒有了,因?yàn)樵黾拥母采w索引已經(jīng)足夠把所有的信息都select出來。就這么簡單。
實(shí)際上,在sqlserver 2023中,如果用profiler來抓eventid:1222,那么會(huì)出現(xiàn)一個(gè)死鎖的圖,很直觀的說。
下面的方法,有助于將死鎖減至最少(詳細(xì)情況,請看SQLServer聯(lián)機(jī)幫助,搜索:將死鎖減至最少即可。
按同一順序訪問對象。
避免事務(wù)中的用戶交互。
保持事務(wù)簡短并處于一個(gè)批處理中。
使用較低的隔離級別。
使用基于行版本控制的隔離級別。
將 READ_COMMITTED_SNAPSHOT 數(shù)據(jù)庫選項(xiàng)設(shè)置為 ON,使得已提交讀事務(wù)使用行版本控制。
使用快照隔離。
sql 查詢 數(shù)據(jù)庫鎖隔離級別的介紹就聊到這里吧,感謝你花時(shí)間閱讀本站內(nèi)容,更多關(guān)于sql 查詢 數(shù)據(jù)庫鎖隔離級別,SQL查詢:了解數(shù)據(jù)庫鎖隔離級別,如何解除sql server數(shù)據(jù)庫數(shù)據(jù)被鎖定,如何處理SQL Server死鎖問題的信息別忘了在本站進(jìn)行查找喔。
成都服務(wù)器租用選創(chuàng)新互聯(lián),先試用再開通。
創(chuàng)新互聯(lián)(www.cdcxhl.com)提供簡單好用,價(jià)格厚道的香港/美國云服務(wù)器和獨(dú)立服務(wù)器。物理服務(wù)器托管租用:四川成都、綿陽、重慶、貴陽機(jī)房服務(wù)器托管租用。
文章名稱:SQL查詢:了解數(shù)據(jù)庫鎖隔離級別 (sql 查詢 數(shù)據(jù)庫鎖隔離級別)
網(wǎng)站地址:http://www.dlmjj.cn/article/dpjihjd.html


咨詢
建站咨詢
