SQL?Server中鎖的用法
鎖是一種防止在某對(duì)象執(zhí)行動(dòng)作的一個(gè)進(jìn)程與已在該對(duì)象上執(zhí)行的其他進(jìn)行相沖突的機(jī)制。也就是說,如果有其他人在操作某個(gè)對(duì)象,那么你舊不能在該對(duì)象上進(jìn)行操作。你能否執(zhí)行操作取決于其他用戶正在進(jìn)行的操作。
通過鎖可以防止的問題
鎖可以解決以下4種主要問題:
1、臟讀
如果一個(gè)事務(wù)讀取的記錄是另一個(gè)未完成事務(wù)的一部分,那么這時(shí)就發(fā)生了臟讀。如果第一個(gè)事務(wù)正常完成,那么就有什么問題。但是,如果前一個(gè)事務(wù)回滾了呢,那將從數(shù)據(jù)庫從未發(fā)生的事務(wù)中獲取了信息。
2、非重復(fù)性讀取
很容易將非重復(fù)性讀取和臟讀混淆。如果一個(gè)事務(wù)中兩次讀取記錄,而另一個(gè)事務(wù)在這期間改變了數(shù)據(jù),就會(huì)發(fā)生非重復(fù)性讀取。
例如,一個(gè)銀行賬戶的余額是不允許小于0的。如果一個(gè)事務(wù)讀取了某賬戶的余額為125元,此時(shí)另一事務(wù)也讀取了125元,如果兩個(gè)事務(wù)都扣費(fèi)100元,那么這時(shí)數(shù)據(jù)庫的余額就變成了-75元。
有兩種方式可以防止這個(gè)問題:
- 創(chuàng)建CHECK約束并監(jiān)控547錯(cuò)誤
- 將隔離級(jí)別設(shè)置為REPEATABLEREAD或SERIALIZABLE
CHECK約束看上去相當(dāng)直觀。要知道的是,這是一種被動(dòng)的而非主動(dòng)的方法。然而,在很多情況下可能需要使用非重復(fù)性讀取,所以這在很多情況下是首選。
3、幻讀
幻讀發(fā)生的概率非常小,只有在非常偶然的情況下才會(huì)發(fā)生。
比如,你想將一張工資表里所有低于100的人的工資,提高到100元。你可能會(huì)執(zhí)行以下SQL語句:
UPDATE tb_Money SET Salary = 100 WHERE Salary < 100
這樣的語句,通常情況下,沒有問題。但是如果,你在UPDATE的過程中,有人恰好有INSERT了一條工資低于100的數(shù)據(jù),因?yàn)檫@是一個(gè)全新的數(shù)據(jù)航,所以沒有被鎖定,而且它會(huì)被漏過Update。
要解決這個(gè)問題,唯一的方法是設(shè)定事務(wù)隔離級(jí)別為SERIALIZABLE,在這種情況下,任何對(duì)表的更新都不能放入WHERE子句中,否則他們將被鎖在外面。
4、丟失更新
丟失更新發(fā)生在一個(gè)更新成功寫入數(shù)據(jù)庫后,而又意外地被另一個(gè)事務(wù)重寫時(shí)。這是怎么發(fā)生的呢?如果有兩個(gè)事務(wù)讀取整個(gè)記錄,然后其中一個(gè)向記錄寫入了更新信息,而另一個(gè)事務(wù)也向該記錄寫入更新信息,這是就會(huì)出現(xiàn)丟失更新。
有個(gè)例子寫得很好,這里照敲下來吧。假如你是公司的一位信用分析員,你接到客戶X打開的電話,說他已達(dá)到它的信用額度上限,想申請?jiān)黾宇~度,所以你查看了這位客戶的信息,你發(fā)現(xiàn)他的信用額度是5000,并且看他每次都能按時(shí)付款。
當(dāng)你在查看的時(shí)候,信用部門的另一位員工也讀取了客戶X的記錄,并輸入信息改變了客戶的地址。它讀取的記錄也顯示信用額度為5000。
這時(shí)你決定把客戶X的信用額度提高到10000,并且按下了Enter鍵,數(shù)據(jù)庫現(xiàn)在顯示客戶X的信用額度為10000。
Sally現(xiàn)在也更新了客戶X的地址,但是她仍然使用和您一樣的編輯屏幕,也就是說,她更新了整個(gè)記錄。還記得她屏幕上顯示的信用額度嗎?是5000.數(shù)據(jù)庫現(xiàn)在又一次顯示客戶X的信用額度為5000。你的更新丟失了。
解決這個(gè)問題的方法取決于你讀取某數(shù)據(jù)和要更新數(shù)據(jù)的這段時(shí)間內(nèi),代碼以何種方式識(shí)別出另一連接已經(jīng)更新了該記錄。這個(gè)識(shí)別的方式取決于你所使用的訪問方法。
可以鎖定的資源
對(duì)于SQL Server來說,有6種可鎖定的資源,而且它們形成了一個(gè)層次結(jié)構(gòu)。鎖的層次越高,它的粒度就越粗。按粒度由粗到細(xì)排列,這些資源包括:
- 數(shù)據(jù)庫:鎖定整個(gè)數(shù)據(jù)庫。這通常發(fā)生在整個(gè)數(shù)據(jù)庫模式改變的時(shí)候。
- 表:鎖定整個(gè)表。這包含了與該表相關(guān)聯(lián)的所有數(shù)據(jù)相關(guān)的對(duì)象,包括實(shí)際的數(shù)據(jù)行(每一行)以及與該表相關(guān)聯(lián)的所有索引中的鍵。
- 區(qū)段:鎖定整個(gè)區(qū)段。因?yàn)橐粋€(gè)區(qū)段由8頁組成,所以區(qū)段鎖定是指鎖定控制了區(qū)段、控制了該區(qū)段內(nèi)8個(gè)數(shù)據(jù)或索引頁以及這8頁中的所有數(shù)據(jù)航。
- 頁:鎖定該頁中的所有數(shù)據(jù)或索引鍵。
- 鍵:在索引中的特定鍵或一系間上有鎖。相同索引頁中的其他鍵不受影響。
- 行或行標(biāo)識(shí)符:雖然從技術(shù)上將,鎖是放在行標(biāo)識(shí)符上的,但是本質(zhì)上,它鎖定了整個(gè)數(shù)據(jù)行。
鎖升級(jí)和鎖對(duì)性能的影響
升級(jí)是指能夠認(rèn)識(shí)到維持一個(gè)較細(xì)的粒度(例如,行鎖而不是頁鎖),只在被鎖定的項(xiàng)數(shù)較少時(shí)有意義。而隨著越來越多的項(xiàng)目被鎖定,維護(hù)這些鎖的系統(tǒng)開銷實(shí)際上會(huì)影響性能。這會(huì)導(dǎo)致所持續(xù)更長的時(shí)間。
當(dāng)維持鎖的數(shù)量達(dá)到一定限度時(shí),則鎖升級(jí)為下一個(gè)更高的層次,并且將不需要再如此緊密地管理低層次的鎖(釋放資源,而且有助于提升速度)。
注意,升級(jí)是基于鎖的數(shù)量,而不是用戶的數(shù)量。這里的重點(diǎn)是,可以通過執(zhí)行大量的更新來單獨(dú)地鎖定表-行鎖可以升級(jí)為頁鎖,頁鎖可以升級(jí)為表鎖。這意味著可能將所有其他用戶鎖在該表之外。如果查詢使用了多個(gè)表,則它很可能將每個(gè)人鎖在這些表之外。
鎖定模式
除了需要考慮鎖定的資源層次以外,還要考慮查詢將要獲得的鎖定模式,就像需要對(duì)不同的資源進(jìn)行鎖定一樣,也有不同的鎖定模式。一些模式是互相排斥的。一些模式什么都不做,只修改其他的模式。模式是否可以一起使用取決于他們是否是兼容的。
1、共享鎖
這是最基本的一種鎖。共享鎖用于只需要讀取數(shù)據(jù)的時(shí)候,也就是說,共享鎖鎖定時(shí),不會(huì)進(jìn)行改變內(nèi)容的操作,其他用戶允許讀取。
共享鎖能和其他共享鎖兼容。雖然共享鎖不介意其他鎖的存在,但是有些鎖并不能和共享鎖共存。
共享鎖告訴其他鎖,某用戶已經(jīng)在那邊了,它們并不提供很多的功能,但是不能忽略它們。然而,共享鎖能做的是防止用戶執(zhí)行臟讀。
2、排它鎖
排它鎖顧名思義,排它鎖不與其他任何鎖兼容。如果有任何其他其他鎖存在,則不能使用排他鎖,而且當(dāng)排他鎖仍然起作用時(shí),他們不允許在資源之上創(chuàng)建任何形式的新鎖。這可以防止兩個(gè)人同時(shí)更新、刪除或執(zhí)行任何操作。
3、更新鎖
更新鎖是共享鎖和排他鎖的混合。更新鎖是一種特殊的占位符。為了能執(zhí)行UPDATE,需要驗(yàn)證WHERE子句來指出想要更新的具體的數(shù)據(jù)行。這意味著只需要一個(gè)共享鎖,直到真正地進(jìn)行物理更新。在物理更新期間,需要一個(gè)排他鎖。
- 第一個(gè)階段指出了滿足WHERE子句條件的內(nèi)容,這是更新查詢的一部分,該查詢有一個(gè)更新鎖。
- 第二個(gè)階段是如果決定執(zhí)行更新,那么鎖將升級(jí)為排他鎖。否則,將把鎖轉(zhuǎn)換為共享鎖。
這樣做的好處是它防止了死鎖。死鎖本身不是一種鎖定類型,而是一種已經(jīng)形成矛盾的狀況,兩個(gè)鎖在互相等待,多個(gè)鎖形成一個(gè)環(huán)在等待前面的事務(wù)清除資源。
如果沒有更新鎖,死鎖會(huì)一直出現(xiàn)。兩個(gè)更新查詢會(huì)在共享模式下運(yùn)行。Query A完成了它的查詢工作并準(zhǔn)備進(jìn)行物理更新。它想升級(jí)為排他鎖,但是不可以這么做,因?yàn)镼uery B正在完成查詢。除非Query B需要進(jìn)行物理更新,否則它會(huì)完成查詢。為了做到這點(diǎn),Query B必須升級(jí)為排他鎖,但是不能這么做,因?yàn)镼uery A正在等待。這樣就造成了僵局。
而更新鎖阻止建立其他的更新鎖。第二個(gè)事務(wù)只要嘗試取得一個(gè)更新鎖,它們就會(huì)進(jìn)入等待狀態(tài),直到超時(shí)為止-將不會(huì)授予這個(gè)鎖。如果第一個(gè)鎖在鎖超時(shí)之前清除的話,則鎖定會(huì)授予給新的請求者,并且這個(gè)處理會(huì)繼續(xù)下去。如果不清楚,則會(huì)發(fā)生錯(cuò)誤。
更新鎖只與共享鎖以及意向共享鎖相兼容。
4、意向鎖
意向鎖是什么意思呢?就是說,加入你鎖定了某一行,那么同時(shí)也加了表的意向鎖(不允許其他人通過表鎖來妨礙你)。
意向鎖是真正的占位符,它用來處理對(duì)象層次問題的。假設(shè)一下如下情況:已對(duì)某一行建立了鎖,但是有人想在頁上或區(qū)段上建立所,或者是修改表。你肯定不想讓另一個(gè)事務(wù)通過達(dá)到更高的層次來妨礙你。
如果沒有意向鎖,那么較高層次的對(duì)象將不會(huì)知道在較低層次上有鎖。意向鎖可改進(jìn)性能,因?yàn)镾QL Server只需要在表層次上檢查意向鎖(而不需要檢查表上的每個(gè)行鎖或者頁鎖),以此來決定事務(wù)是否可以安全地鎖定整個(gè)表。
意向鎖分為以下3種不同的類型:
- 意向共享鎖:該意向鎖指已經(jīng)或者將要在層次結(jié)構(gòu)的一些較低點(diǎn)處建立共享鎖。
- 意向排他鎖:它與意向共享鎖一樣,但是將會(huì)在低層項(xiàng)上設(shè)置排他鎖。
- 共享意向排他鎖:它指已經(jīng)或?qū)?huì)在對(duì)象層次結(jié)構(gòu)下面建立共享鎖,但目的是為了修改數(shù)據(jù),所以它會(huì)在某個(gè)時(shí)刻成為意向排它鎖。
5、模式鎖
模式鎖分為以下兩種。
- 模式修改鎖:對(duì)對(duì)象進(jìn)行模式改變。在Sch-M鎖期間,不能對(duì)對(duì)象進(jìn)行查詢或其他CREATE、ALTER或DROP語句的操作。
- 模式穩(wěn)定鎖鎖定:它和共享鎖很相似;這個(gè)鎖的唯一目的是方式模式修改鎖,因?yàn)樵谠搶?duì)象上已有其他查詢(或CREATE、ALTER、DROP語句)的鎖。它與其他所有的鎖定相兼容。
6、批量更新鎖
批量更新鎖(BU)只是一種略有不同的表鎖定變體形式。批量更新鎖允許并行加載數(shù)據(jù)。也就是說,對(duì)于其他任何普通操作(T-SQL)都會(huì)將表鎖定,但可以同時(shí)執(zhí)行多個(gè)BULK INSERT或bcp操作。
鎖的兼容性
鎖的資源鎖定模式的兼容性表格,現(xiàn)有鎖以列顯示,要兼容的鎖以行顯示。
鎖的類型 | 意向共享鎖(IS) | 共享鎖(S) | 更新鎖(U) | 意向排他鎖(IX) | 共享意向排它鎖(SIX) | 排他鎖(X) |
---|---|---|---|---|---|---|
意向共享鎖(IS) | 是 | 是 | 是 | 是 | 是 | 否 |
共享鎖(S) | 是 | 是 | 是 | 否 | 否 | 否 |
更新鎖(U) | 是 | 是 | 否 | 否 | 否 | 否 |
意向排他鎖(IX) | 是 | 否 | 否 | 是 | 否 | 否 |
共享意向排它鎖(SIX) | 是 | 否 | 否 | 否 | 否 | 否 |
排他鎖(X) | 否 | 否 | 否 | 否 | 否 | 否 |
另外:
- Sch-S與出Sch-M以外的所有鎖定模式相兼容。
- Sch-M和所有的鎖定模式不兼容。
- BU只與模式穩(wěn)定性鎖以及其他的批量更新鎖相兼容。
有時(shí)想要在查詢中或在整個(gè)事務(wù)中對(duì)鎖定有更多的控制。可以通過使用優(yōu)化器提示(optimizer hints)來實(shí)現(xiàn)這一點(diǎn)。
優(yōu)化器提示明確告訴SQL Server將一個(gè)鎖升級(jí)為特有的層次。這些提示信息包含在將要影響的表的名稱之后。
優(yōu)化器提示是一個(gè)高級(jí)主題,有經(jīng)驗(yàn)的SQL Server開發(fā)人員會(huì)經(jīng)常使用它,并且他們相當(dāng)重視它。
使用Management Studio確定鎖
查看鎖的最好方式是使用Management Studio。通過使用Activity Monitor,Management Studio會(huì)以兩種方式顯示鎖-通過processId或object。
為了使用Management Studio顯示鎖,只要導(dǎo)航到<Server>的Activity Monitor節(jié)點(diǎn),其中的<Server>是監(jiān)控其活動(dòng)的服務(wù)器的頂級(jí)節(jié)點(diǎn)。
展開感興趣的節(jié)點(diǎn)(Overview部分默認(rèn)展開),可以通過滾動(dòng)條查看大量度量值-包括當(dāng)前系統(tǒng)中有效的鎖。
顯示界面如下:
設(shè)置隔離級(jí)別
事務(wù)和鎖之間的聯(lián)系是很緊密的。默認(rèn)情況下,一旦創(chuàng)建了任何與數(shù)據(jù)修改相關(guān)的鎖,該鎖定就會(huì)在整個(gè)事務(wù)期間存在。如果有一個(gè)大型事務(wù),就意味著將在很長一段時(shí)間內(nèi)阻止其他進(jìn)程訪問鎖定的對(duì)象。這明顯是有問題的。
事務(wù)有5種隔離級(jí)別:
- READ COMMITTED
- READ UNCOMMITTED
- REPEATABLE READ
- SERIALIZABLE
- SNAPSHOT
在這些隔離級(jí)別之間進(jìn)行切換的語法也相當(dāng)直觀:
SET TRANSACTION ISOLATION LEVEL < READ COMMITTED | READ UNCOMMITTED | REPEATABLE READ | SERIALIZABLE | SNAPSHOT >
對(duì)隔離級(jí)別的修改只會(huì)影響到當(dāng)前的連接-所以不必?fù)?dān)心會(huì)影響到其他的用戶。其他用戶也影響不了你。
1、READ COMMITTED
默認(rèn)情況就是這個(gè),通過READ COMMITTED,任何創(chuàng)建的共享鎖將在創(chuàng)建它們的語句完成后自動(dòng)釋放。也就是說,如果啟動(dòng)了一個(gè)事務(wù),運(yùn)行了一些語句,然后運(yùn)行SELECT語句,再運(yùn)行一些其他的語句,那么當(dāng)SELECT語句完成的時(shí)候,與SELECT語句相關(guān)聯(lián)的鎖就會(huì)釋放 - SQL Server并不會(huì)等到事務(wù)結(jié)束。
動(dòng)作查詢(UPDATE、DELETE、INSERT)有點(diǎn)不同。如果事務(wù)執(zhí)行了修改數(shù)據(jù)的查詢,則這些鎖將會(huì)在事務(wù)期間保持有效。
通過設(shè)置READ COMMITTED這一默認(rèn)隔離級(jí)別,可以確定有足夠的數(shù)據(jù)完整性來防止臟讀。然而,仍會(huì)發(fā)生非重復(fù)性讀取和幻讀。
2、READ UNCOMMITTED
READ UNCOMMITTED是所有隔離級(jí)別中最危險(xiǎn)的,但是它在速度方面有最好的性能。
設(shè)置隔離級(jí)別為READ UNCOMMITTED將告訴SQL Server不要設(shè)置任何鎖,也不要事先任何鎖。
鎖既是你的保護(hù)者,同時(shí)也是你的敵人。鎖可以防止數(shù)據(jù)完整性問題,但是鎖也經(jīng)常妨礙或阻止你訪問需要的數(shù)據(jù)。由于此鎖存在臟讀的危險(xiǎn),因此此鎖只能應(yīng)用于并非十分精確的環(huán)境中。
3、REPEATABLE READ
REPEATABLE READ會(huì)稍微地將隔離級(jí)別升級(jí),并提供一個(gè)額外的并發(fā)保護(hù)層,這不僅能防止臟讀,而且能防止非重復(fù)性讀取。
防止非重復(fù)性讀取是很大的優(yōu)勢,但是直到事務(wù)結(jié)束還保持共享鎖會(huì)阻止用戶訪問對(duì)象,因此會(huì)影響效率。推薦使用其他的數(shù)據(jù)完整性選項(xiàng),例如CHECK約束,而不是采用這個(gè)選擇。
與REPEATABLE READ隔離級(jí)別等價(jià)的優(yōu)化器提示是REPEATABLEREAD(除了一個(gè)空格,兩者并無不同)。
4、SERIALIZABLE
SERIALIZABLE是堡壘級(jí)的隔離級(jí)別。除了丟失更新以外,它防止所有形式的并發(fā)問題。甚至能防止幻讀。
如果設(shè)置隔離級(jí)別為SERIALIZABLE,就意味著對(duì)事物使用的表進(jìn)行的任何UPDATE、DELETE、INSERT操作絕對(duì)不滿足該事務(wù)中任何語句的WHERE子句的條件。從本質(zhì)上說,如果用戶想執(zhí)行一些事務(wù)感興趣的事情,那么必須等到該事務(wù)完成的時(shí)候。
SERIALIZABLE隔離級(jí)別也可以通過查詢中使用SERIALIZABLE或HOLDLOCK優(yōu)化器提示模擬。再次申明,類似于READ UNCOMMITTED和NOLOCK,前者不需要每次都設(shè)置,而后者需要把隔離級(jí)別設(shè)置回來。
5、SNAPSHOT
SNAPSHOT是最新的一種隔離級(jí)別,非常想READ COMMITTED和READ UNCOMMITTED的組合。要注意的是,SNAPSHOT默認(rèn)是不可用的-只有為數(shù)據(jù)庫打開了ALLOW_SNAPSHOT_ISOLATION特殊選項(xiàng)時(shí),SNAPSHOT才可用。
和READ UNCOMMITED一樣,SNAPSHOT并不創(chuàng)建任何鎖,也不實(shí)現(xiàn)人和所。兩者的主要區(qū)別是它們識(shí)別數(shù)據(jù)庫中不同時(shí)段發(fā)生的更改。數(shù)據(jù)庫中的更改,不管何時(shí)或是否提交,都會(huì)被運(yùn)行READ UNCOMMITTED隔離級(jí)別的查詢看到。而使用SNAPSHOT,只能看到在SNAPSHOT事務(wù)開始之前提交的更改。從SNAPSHOT事務(wù)一開始執(zhí)行,所有查看到的數(shù)據(jù)就和在時(shí)間開始時(shí)提交的一樣。
處理死鎖
死鎖的錯(cuò)誤號(hào)是1205。
如果一個(gè)鎖由于另一個(gè)鎖占有資源而不能完成應(yīng)該做的清除資源工作,就會(huì)導(dǎo)致死鎖;反之亦然。當(dāng)發(fā)生死鎖時(shí),需要其中的一方贏得這場斗爭,所以SQL Server選擇一個(gè)死鎖犧牲者,對(duì)死鎖犧牲者的事務(wù)進(jìn)行回滾,并且通過1205錯(cuò)誤來通知發(fā)生了死鎖。另外一個(gè)事務(wù)將繼續(xù)正常地運(yùn)行。
1、判斷死鎖的方式
每隔5秒鐘,SQL Server就會(huì)檢查所有當(dāng)前的事務(wù),了解他們在等待什么還未被授予的鎖。然后再一次重新檢查所有打開的鎖請求的狀態(tài),如果先前請求中有一個(gè)還沒有被授予,則它會(huì)遞歸地檢查所有打開的事務(wù),尋找鎖定請求的循環(huán)鏈。如果SQL Server找到這樣的村換連,則將會(huì)選擇一個(gè)或更多的死鎖犧牲者。
2、選擇死鎖犧牲者的方式
默認(rèn)情況下,基于相關(guān)事務(wù)的"代價(jià)",選擇死鎖犧牲者。SQL Server將會(huì)選擇回滾代價(jià)最低的事務(wù)。在一定程度上,可以使用SQL Server中的DEADLOCK_PRIORITY SET選項(xiàng)來重寫它。
3、避免死鎖
避免死鎖的常用規(guī)則
- 按相同的順序使用對(duì)象
- 使事務(wù)盡可能簡短并且在一個(gè)批處理中。
- 盡可能使用最低的事務(wù)隔離級(jí)別。
- 在同一事務(wù)中不允許無限度的中斷。
- 在控制環(huán)境中,使用綁定連接。
1、按相同的順序使用對(duì)象
例如有兩個(gè)表:Suppliers和Products。假設(shè)有兩個(gè)進(jìn)程將使用這兩個(gè)表。進(jìn)程1接受庫存輸入,用手頭新的產(chǎn)品總量更新Products表,接下來用已經(jīng)購買的產(chǎn)品總量來更新Suppliers表。進(jìn)程2記錄銷售數(shù)據(jù),它在Supperlier表中更新銷售產(chǎn)品的總量,然后在Product中減少庫存數(shù)量。
如果同時(shí)運(yùn)行這兩個(gè)進(jìn)程,那么就有可能碰到麻煩。進(jìn)程1試圖獲取Product表上的一個(gè)排他鎖。進(jìn)程2將在Suppliers表上獲取一個(gè)排他鎖。然后進(jìn)程1將試圖獲取Suppliers表上的一個(gè)鎖,但是進(jìn)程1必須等到進(jìn)程2清除了現(xiàn)有的鎖。同時(shí)進(jìn)程2也在等待進(jìn)程1清除現(xiàn)有鎖。
上面的例子是,兩個(gè)進(jìn)程用相反的順序,鎖住兩個(gè)表,這樣就很容易發(fā)生死鎖。
如果我們將進(jìn)程2改成首先在Products減少庫存數(shù)量,接著在Suppliers表中更新銷售產(chǎn)品的總數(shù)量。兩個(gè)進(jìn)程以相同的順序訪問兩張表,這樣就能夠減少死鎖的發(fā)生。
2、使事務(wù)盡可能簡短
保持事務(wù)的簡短將不會(huì)讓你付出任何的代價(jià)。在事務(wù)中放入想要的內(nèi)容,把不需要的內(nèi)容拿出來,就這么簡單。它的原理并不復(fù)雜-事務(wù)打開的時(shí)間越長,它觸及的內(nèi)容就越多,那么其他一些進(jìn)程想要得到正在使用的一個(gè)或者多個(gè)對(duì)象的可能性就越大。如果要保持事務(wù)簡短,那么就將最小化可能引起死鎖的對(duì)象的數(shù)量,還將減少鎖定對(duì)象的時(shí)間。原理就如此簡單。
3、盡可能使用最低的事務(wù)隔離級(jí)別
使用較低的隔離級(jí)別和較高的隔離級(jí)別相比,共享鎖持續(xù)的時(shí)間更短,因此會(huì)減少鎖的競爭。
4、不要采用允許無限中斷的事務(wù)
當(dāng)開始執(zhí)行某種開放式進(jìn)程時(shí)間,不要?jiǎng)?chuàng)建將一直占有資源的鎖。通常,指的是用戶交互,但它也可能是允許無限等待的任何進(jìn)程。
到此這篇關(guān)于SQL Server鎖的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
SqlServer存儲(chǔ)過程實(shí)現(xiàn)及拼接sql的注意點(diǎn)
這篇文章主要介紹了SqlServer存儲(chǔ)過程實(shí)現(xiàn)及拼接sql的注意點(diǎn)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-07-07必須會(huì)的SQL語句(六) 數(shù)據(jù)查詢
這篇文章主要介紹了sqlserver中數(shù)據(jù)查詢方法,需要的朋友可以參考下2015-01-01SQLSERVER記錄登錄用戶的登錄時(shí)間(自寫腳本)
下面是本人寫的一個(gè)腳本,我的實(shí)現(xiàn)原理是使用觸發(fā)器,觸發(fā)器是登錄觸發(fā)器,范圍是整個(gè)服務(wù)器范圍,如果有人登錄過,就使用 bcp命令把登錄信息記錄日志文件,感興趣的朋友可以了解下,或許本文的知識(shí)點(diǎn)對(duì)你有所幫助2013-02-02idea連接sql?sever2019圖文教程(超詳細(xì))
這篇文章主要介紹了idea連接sql?sever2019的圖文教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-04-04分享網(wǎng)站群發(fā)站內(nèi)信數(shù)據(jù)庫表設(shè)計(jì)
本文和大家分享一下網(wǎng)站站內(nèi)信實(shí)現(xiàn)表設(shè)計(jì)的功能。需要的朋友可以參考下。2010-03-03SQL?Server?2019完整安裝教程(最新最詳細(xì)!)
SQL Server是一款Microsoft公司推出的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),下面這篇文章主要給大家介紹了關(guān)于SQL?Server?2019完整安裝教程的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),本文介紹的是最新最詳細(xì),需要的朋友可以參考下2023-02-02sqlserver四舍五入使用round函數(shù)及cast和convert函數(shù)
大家在遇到sqlserver四舍五入除了用round函數(shù)還有沒有其他方法呢?下面小編給大家介紹使用cast和convert函數(shù),感興趣的朋友一起學(xué)習(xí)吧2015-11-11還原Sql?Server數(shù)據(jù)庫BAK備份文件的3種方式以及常見錯(cuò)誤總結(jié)
日常后端開發(fā)中,我們有時(shí)候需要查看之前備份數(shù)據(jù)庫的信息用于排錯(cuò)糾正項(xiàng)目問題,下面這篇文章主要給大家介紹了關(guān)于還原Sql?Server數(shù)據(jù)庫BAK備份文件的3種方式以及常見錯(cuò)誤的相關(guān)資料,需要的朋友可以參考下2023-02-02