最近2018中文字幕在日韩欧美国产成人片_国产日韩精品一区二区在线_在线观看成年美女黄网色视频_国产精品一区三区五区_国产精彩刺激乱对白_看黄色黄大色黄片免费_人人超碰自拍cao_国产高清av在线_亚洲精品电影av_日韩美女尤物视频网站

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
sqlserver悲觀鎖,sqlserver死鎖解決辦法

Sql server08數(shù)據(jù)庫執(zhí)行什么操作的時(shí)候會加S鎖,IX鎖和SIX鎖

一. 為什么要引入鎖

成都創(chuàng)新互聯(lián)公司專業(yè)為企業(yè)提供烏海網(wǎng)站建設(shè)、烏海做網(wǎng)站、烏海網(wǎng)站設(shè)計(jì)、烏海網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)與制作、烏海企業(yè)網(wǎng)站模板建站服務(wù),十載烏海做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。

多個(gè)用戶同時(shí)對數(shù)據(jù)庫的并發(fā)操作時(shí)會帶來以下數(shù)據(jù)不一致的問題:

丟失更新

A,B兩個(gè)用戶讀同一數(shù)據(jù)并進(jìn)行修改,其中一個(gè)用戶的修改結(jié)果破壞了另一個(gè)修改的結(jié)果,比如訂票系統(tǒng)

臟讀

A用戶修改了數(shù)據(jù),隨后B用戶又讀出該數(shù)據(jù),但A用戶因?yàn)槟承┰蛉∠藢?shù)據(jù)的修改,數(shù)據(jù)恢復(fù)原值,此時(shí)B得到的數(shù)據(jù)就與數(shù)據(jù)庫內(nèi)的數(shù)據(jù)產(chǎn)生了不一致

不可重復(fù)讀

A用戶讀取數(shù)據(jù),隨后B用戶讀出該數(shù)據(jù)并修改,此時(shí)A用戶再讀取數(shù)據(jù)時(shí)發(fā)現(xiàn)前后兩次的值不一致

并發(fā)控制的主要方法是封鎖,鎖就是在一段時(shí)間內(nèi)禁止用戶做某些操作以避免產(chǎn)生數(shù)據(jù)不一致

二 鎖的分類

鎖的類別有兩種分法:

1. 從數(shù)據(jù)庫系統(tǒng)的角度來看:分為獨(dú)占鎖(即排它鎖),共享鎖和更新鎖

MS-SQL Server 使用以下資源鎖模式。

鎖模式 描述

共享 (S) 用于不更改或不更新數(shù)據(jù)的操作(只讀操作),如 SELECT 語句。

更新 (U) 用于可更新的資源中。防止當(dāng)多個(gè)會話在讀取、鎖定以及隨后可能進(jìn)行的資源更新時(shí)發(fā)生常見形式的死鎖。

排它 (X) 用于數(shù)據(jù)修改操作,例如 INSERT、UPDATE 或 DELETE。確保不會同時(shí)同一資源進(jìn)行多重更新。

意向鎖 用于建立鎖的層次結(jié)構(gòu)。意向鎖的類型為:意向共享 (IS)、意向排它 (IX) 以及與意向排它共享 (SIX)。

架構(gòu)鎖 在執(zhí)行依賴于表架構(gòu)的操作時(shí)使用。架構(gòu)鎖的類型為:架構(gòu)修改 (Sch-M) 和架構(gòu)穩(wěn)定性 (Sch-S)。

大容量更新 (BU) 向表中大容量復(fù)制數(shù)據(jù)并指定了 TABLOCK 提示時(shí)使用。

共享鎖

共享 (S) 鎖允許并發(fā)事務(wù)讀取 (SELECT) 一個(gè)資源。資源上存在共享 (S) 鎖時(shí),任何其它事務(wù)都不能修改數(shù)據(jù)。一旦已經(jīng)讀取數(shù)據(jù),便立即釋放資源上的共享 (S) 鎖,除非將事務(wù)隔離級別設(shè)置為可重復(fù)讀或更高級別,或者在事務(wù)生存周期內(nèi)用鎖定提示保留共享 (S) 鎖。

更新鎖

更新 (U) 鎖可以防止通常形式的死鎖。一般更新模式由一個(gè)事務(wù)組成,此事務(wù)讀取記錄,獲取資源(頁或行)的共享 (S) 鎖,然后修改行,此操作要求鎖轉(zhuǎn)換為排它 (X) 鎖。如果兩個(gè)事務(wù)獲得了資源上的共享模式鎖,然后試圖同時(shí)更新數(shù)據(jù),則一個(gè)事務(wù)嘗試將鎖轉(zhuǎn)換為排它 (X) 鎖。共享模式到排它鎖的轉(zhuǎn)換必須等待一段時(shí)間,因?yàn)橐粋€(gè)事務(wù)的排它鎖與其它事務(wù)的共享模式鎖不兼容;發(fā)生鎖等待。第二個(gè)事務(wù)試圖獲取排它 (X) 鎖以進(jìn)行更新。由于兩個(gè)事務(wù)都要轉(zhuǎn)換為排它 (X) 鎖,并且每個(gè)事務(wù)都等待另一個(gè)事務(wù)釋放共享模式鎖,因此發(fā)生死鎖。

若要避免這種潛在的死鎖問題,請使用更新 (U) 鎖。一次只有一個(gè)事務(wù)可以獲得資源的更新 (U) 鎖。如果事務(wù)修改資源,則更新 (U) 鎖轉(zhuǎn)換為排它 (X) 鎖。否則,鎖轉(zhuǎn)換為共享鎖。

排它鎖

排它 (X) 鎖可以防止并發(fā)事務(wù)對資源進(jìn)行訪問。其它事務(wù)不能讀取或修改排它 (X) 鎖鎖定的數(shù)據(jù)。

意向鎖

意向鎖表示 SQL Server 需要在層次結(jié)構(gòu)中的某些底層資源上獲取共享 (S) 鎖或排它 (X) 鎖。例如,放置在表級的共享意向鎖表示事務(wù)打算在表中的頁或行上放置共享 (S) 鎖。在表級設(shè)置意向鎖可防止另一個(gè)事務(wù)隨后在包含那一頁的表上獲取排它 (X) 鎖。意向鎖可以提高性能,因?yàn)?SQL Server 僅在表級檢查意向鎖來確定事務(wù)是否可以安全地獲取該表上的鎖。而無須檢查表中的每行或每頁上的鎖以確定事務(wù)是否可以鎖定整個(gè)表。

意向鎖包括意向共享 (IS)、意向排它 (IX) 以及與意向排它共享 (SIX)。

鎖模式 描述

意向共享 (IS) 通過在各資源上放置 S 鎖,表明事務(wù)的意向是讀取層次結(jié)構(gòu)中的部分(而不是全部)底層資源。

意向排它 (IX) 通過在各資源上放置 X 鎖,表明事務(wù)的意向是修改層次結(jié)構(gòu)中的部分(而不是全部)底層資源。IX 是 IS 的超集。

與意向排它共享 (SIX) 通過在各資源上放置 IX 鎖,表明事務(wù)的意向是讀取層次結(jié)構(gòu)中的全部底層資源并修改部分(而不是全部)底層資源。允許頂層資源上的并發(fā) IS 鎖。例如,表的 SIX 鎖在表上放置一個(gè) SIX 鎖(允許并發(fā) IS 鎖),在當(dāng)前所修改頁上放置 IX 鎖(在已修改行上放置 X 鎖)。雖然每個(gè)資源在一段時(shí)間內(nèi)只能有一個(gè) SIX 鎖,以防止其它事務(wù)對資源進(jìn)行更新,但是其它事務(wù)可以通過獲取表級的 IS 鎖來讀取層次結(jié)構(gòu)中的底層資源。

獨(dú)占鎖:只允許進(jìn)行鎖定操作的程序使用,其他任何對他的操作均不會被接受。執(zhí)行數(shù)據(jù)更新命令時(shí),SQL Server會自動(dòng)使用獨(dú)占鎖。當(dāng)對象上有其他鎖存在時(shí),無法對其加獨(dú)占鎖。

共享鎖:共享鎖鎖定的資源可以被其他用戶讀取,但其他用戶無法修改它,在執(zhí)行Select時(shí),SQL Server會對對象加共享鎖。

更新鎖:當(dāng)SQL Server準(zhǔn)備更新數(shù)據(jù)時(shí),它首先對數(shù)據(jù)對象作更新鎖鎖定,這樣數(shù)據(jù)將不能被修改,但可以讀取。等到SQL Server確定要進(jìn)行更新數(shù)據(jù)操作時(shí),他會自動(dòng)將更新鎖換為獨(dú)占鎖,當(dāng)對象上有其他鎖存在時(shí),無法對其加更新鎖。

2. 從程序員的角度看:分為樂觀鎖和悲觀鎖。

樂觀鎖:完全依靠數(shù)據(jù)庫來管理鎖的工作。

悲觀鎖:程序員自己管理數(shù)據(jù)或?qū)ο笊系逆i處理。

MS-SQLSERVER 使用鎖在多個(gè)同時(shí)在數(shù)據(jù)庫內(nèi)執(zhí)行修改的用戶間實(shí)現(xiàn)悲觀并發(fā)控制

三 鎖的粒度

鎖粒度是被封鎖目標(biāo)的大小,封鎖粒度小則并發(fā)性高,但開銷大,封鎖粒度大則并發(fā)性低但開銷小

SQL Server支持的鎖粒度可以分為為行、頁、鍵、鍵范圍、索引、表或數(shù)據(jù)庫獲取鎖

資源 描述

RID 行標(biāo)識符。用于單獨(dú)鎖定表中的一行。

鍵 索引中的行鎖。用于保護(hù)可串行事務(wù)中的鍵范圍。

頁 8 千字節(jié) (KB) 的數(shù)據(jù)頁或索引頁。

擴(kuò)展盤區(qū) 相鄰的八個(gè)數(shù)據(jù)頁或索引頁構(gòu)成的一組。

表 包括所有數(shù)據(jù)和索引在內(nèi)的整個(gè)表。

DB 數(shù)據(jù)庫。

四 鎖定時(shí)間的長短

鎖保持的時(shí)間長度為保護(hù)所請求級別上的資源所需的時(shí)間長度。

用于保護(hù)讀取操作的共享鎖的保持時(shí)間取決于事務(wù)隔離級別。采用 READ COMMITTED 的默認(rèn)事務(wù)隔離級別時(shí),只在讀取頁的期間內(nèi)控制共享鎖。在掃描中,直到在掃描內(nèi)的下一頁上獲取鎖時(shí)才釋放鎖。如果指定 HOLDLOCK 提示或者將事務(wù)隔離級別設(shè)置為 REPEATABLE READ 或 SERIALIZABLE,則直到事務(wù)結(jié)束才釋放鎖。

根據(jù)為游標(biāo)設(shè)置的并發(fā)選項(xiàng),游標(biāo)可以獲取共享模式的滾動(dòng)鎖以保護(hù)提取。當(dāng)需要滾動(dòng)鎖時(shí),直到下一次提取或關(guān)閉游標(biāo)(以先發(fā)生者為準(zhǔn))時(shí)才釋放滾動(dòng)鎖。但是,如果指定 HOLDLOCK,則直到事務(wù)結(jié)束才釋放滾動(dòng)鎖。

用于保護(hù)更新的排它鎖將直到事務(wù)結(jié)束才釋放。

如果一個(gè)連接試圖獲取一個(gè)鎖,而該鎖與另一個(gè)連接所控制的鎖沖突,則試圖獲取鎖的連接將一直阻塞到:

將沖突鎖釋放而且連接獲取了所請求的鎖。

連接的超時(shí)間隔已到期。默認(rèn)情況下沒有超時(shí)間隔,但是一些應(yīng)用程序設(shè)置超時(shí)間隔以防止無限期等待

五 SQL Server 中鎖的自定義

1 處理死鎖和設(shè)置死鎖優(yōu)先級

死鎖就是多個(gè)用戶申請不同封鎖,由于申請者均擁有一部分封鎖權(quán)而又等待其他用戶擁有的部分封鎖而引起的無休止的等待

可以使用SET DEADLOCK_PRIORITY控制在發(fā)生死鎖情況時(shí)會話的反應(yīng)方式。如果兩個(gè)進(jìn)程都鎖定數(shù)據(jù),并且直到其它進(jìn)程釋放自己的鎖時(shí),每個(gè)進(jìn)程才能釋放自己的鎖,即發(fā)生死鎖情況。

2 處理超時(shí)和設(shè)置鎖超時(shí)持續(xù)時(shí)間。

@@LOCK_TIMEOUT 返回當(dāng)前會話的當(dāng)前鎖超時(shí)設(shè)置,單位為毫秒

SET LOCK_TIMEOUT 設(shè)置允許應(yīng)用程序設(shè)置語句等待阻塞資源的最長時(shí)間。當(dāng)語句等待的時(shí)間大于 LOCK_TIMEOUT 設(shè)置時(shí),系統(tǒng)將自動(dòng)取消阻塞的語句,并給應(yīng)用程序返回"已超過了鎖請求超時(shí)時(shí)段"的 1222 號錯(cuò)誤信息

示例

下例將鎖超時(shí)期限設(shè)置為 1,800 毫秒。

SET LOCK_TIMEOUT 1800

3) 設(shè)置事務(wù)隔離級別。

4 ) 對 SELECT、INSERT、UPDATE 和 DELETE 語句使用表級鎖定提示。

5) 配置索引的鎖定粒度

可以使用 sp_indexoption 系統(tǒng)存儲過程來設(shè)置用于索引的鎖定粒度

六 查看鎖的信息

1 執(zhí)行 EXEC SP_LOCK 報(bào)告有關(guān)鎖的信息

2 查詢分析器中按Ctrl+2可以看到鎖的信息

七 使用注意事項(xiàng)

如何避免死鎖

1 使用事務(wù)時(shí),盡量縮短事務(wù)的邏輯處理過程,及早提交或回滾事務(wù);

2 設(shè)置死鎖超時(shí)參數(shù)為合理范圍,如:3分鐘-10分種;超過時(shí)間,自動(dòng)放棄本次操作,避免進(jìn)程懸掛;

3 優(yōu)化程序,檢查并避免死鎖現(xiàn)象出現(xiàn);

4 .對所有的腳本和SP都要仔細(xì)測試,在正是版本之前。

5 所有的SP都要有錯(cuò)誤處理(通過@error)

6 一般不要修改SQL SERVER事務(wù)的默認(rèn)級別。不推薦強(qiáng)行加鎖

解決問題 如何對行 表 數(shù)據(jù)庫加鎖

八 幾個(gè)有關(guān)鎖的問題

1 如何鎖一個(gè)表的某一行

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

SELECT * FROM table ROWLOCK WHERE id = 1

2 鎖定數(shù)據(jù)庫的一個(gè)表

SELECT * FROM table WITH (HOLDLOCK)

加鎖語句:

sybase:

update 表 set col1=col1 where 1=0 ;

MSSQL:

select col1 from 表 (tablockx) where 1=0 ;

oracle:

LOCK TABLE 表 IN EXCLUSIVE MODE ;

加鎖后其它人不可操作,直到加鎖用戶解鎖,用commit或rollback解鎖

幾個(gè)例子幫助大家加深印象

設(shè)table1(A,B,C)

A B C

a1 b1 c1

a2 b2 c2

a3 b3 c3

1)排它鎖

新建兩個(gè)連接

在第一個(gè)連接中執(zhí)行以下語句

begin tran

update table1

set A='aa'

where B='b2'

waitfor delay '00:00:30' --等待30秒

commit tran

在第二個(gè)連接中執(zhí)行以下語句

begin tran

select * from table1

where B='b2'

commit tran

若同時(shí)執(zhí)行上述兩個(gè)語句,則select查詢必須等待update執(zhí)行完畢才能執(zhí)行即要等待30秒

2)共享鎖

在第一個(gè)連接中執(zhí)行以下語句

begin tran

select * from table1 holdlock -holdlock人為加鎖

where B='b2'

waitfor delay '00:00:30' --等待30秒

commit tran

在第二個(gè)連接中執(zhí)行以下語句

begin tran

select A,C from table1

where B='b2'

update table1

set A='aa'

where B='b2'

commit tran

若同時(shí)執(zhí)行上述兩個(gè)語句,則第二個(gè)連接中的select查詢可以執(zhí)行

而update必須等待第一個(gè)事務(wù)釋放共享鎖轉(zhuǎn)為排它鎖后才能執(zhí)行 即要等待30秒

3)死鎖

增設(shè)table2(D,E)

D E

d1 e1

d2 e2

在第一個(gè)連接中執(zhí)行以下語句

begin tran

update table1

set A='aa'

where B='b2'

waitfor delay '00:00:30'

update table2

set D='d5'

where E='e1'

commit tran

在第二個(gè)連接中執(zhí)行以下語句

begin tran

update table2

set D='d5'

where E='e1'

waitfor delay '00:00:10'

update table1

set A='aa'

where B='b2'

commit tran

同時(shí)執(zhí)行,系統(tǒng)會檢測出死鎖,并中止進(jìn)程

補(bǔ)充一點(diǎn):

Sql Server2000支持的表級鎖定提示

HOLDLOCK 持有共享鎖,直到整個(gè)事務(wù)完成,應(yīng)該在被鎖對象不需要時(shí)立即釋放,等于SERIALIZABLE事務(wù)隔離級別

NOLOCK 語句執(zhí)行時(shí)不發(fā)出共享鎖,允許臟讀 ,等于 READ UNCOMMITTED事務(wù)隔離級別

PAGLOCK 在使用一個(gè)表鎖的地方用多個(gè)頁鎖

READPAST 讓sql server跳過任何鎖定行,執(zhí)行事務(wù),適用于READ UNCOMMITTED事務(wù)隔離級別只跳過RID鎖,不跳過頁,區(qū)域和表鎖

ROWLOCK 強(qiáng)制使用行鎖

TABLOCKX 強(qiáng)制使用獨(dú)占表級鎖,這個(gè)鎖在事務(wù)期間阻止任何其他事務(wù)使用這個(gè)表

UPLOCK 強(qiáng)制在讀表時(shí)使用更新而不用共享鎖

應(yīng)用程序鎖:

應(yīng)用程序鎖就是客戶端代碼生成的鎖,而不是sql server本身生成的鎖

處理應(yīng)用程序鎖的兩個(gè)過程

sp_getapplock 鎖定應(yīng)用程序資源

sp_releaseapplock 為應(yīng)用程序資源解鎖

注意: 鎖定數(shù)據(jù)庫的一個(gè)表的區(qū)別

SELECT * FROM table WITH (HOLDLOCK) 其他事務(wù)可以讀取表,但不能更新刪除

SELECT * FROM table WITH (TABLOCKX) 其他事務(wù)不能讀取表,更新和刪除

Oracle創(chuàng)建悲觀鎖和樂觀鎖

為了得到最大的性能,一般數(shù)據(jù)庫都有并發(fā)機(jī)制,不過帶來的問題就是數(shù)據(jù)訪問的沖突。為了解決這個(gè)問題,大多數(shù)數(shù)據(jù)庫用的方法就是數(shù)據(jù)的鎖定。

數(shù)據(jù)的鎖定分為兩種方法,第一種叫做悲觀鎖,第二種叫做樂觀鎖。什么叫悲觀鎖呢,悲觀鎖顧名思義,就是對數(shù)據(jù)的沖突采取一種悲觀的態(tài)度,也就是說假設(shè)數(shù)據(jù)肯定會沖突,所以在數(shù)據(jù)開始讀取的時(shí)候就把數(shù)據(jù)鎖定住。而樂觀鎖就是認(rèn)為數(shù)據(jù)一般情況下不會造成沖突,所以在數(shù)據(jù)進(jìn)行提交更新的時(shí)候,才會正式對數(shù)據(jù)的沖突與否進(jìn)行檢測,如果發(fā)現(xiàn)沖突了,則讓用戶返回錯(cuò)誤的信息,讓用戶決定如何去做。

先從悲觀鎖開始說。在SqlServer等其余很多數(shù)據(jù)庫中,數(shù)據(jù)的鎖定通常采用頁級鎖的方式,也就是說對一張表內(nèi)的數(shù)據(jù)是一種串行化的更新插入機(jī)制,在任何時(shí)間同一張表只會插1條數(shù)據(jù),別的想插入的數(shù)據(jù)要等到這一條數(shù)據(jù)插完以后才能依次插入。帶來的后果就是性能的降低,在多用戶并發(fā)訪問的時(shí)候,當(dāng)對一張表進(jìn)行頻繁操作時(shí),會發(fā)現(xiàn)響應(yīng)效率很低,數(shù)據(jù)庫經(jīng)常處于一種假死狀態(tài)。而Oracle用的是行級鎖,只是對想鎖定的數(shù)據(jù)才進(jìn)行鎖定,其余的數(shù)據(jù)不相干,所以在對Oracle表中并發(fā)插數(shù)據(jù)的時(shí)候,基本上不會有任何影響。

注:對于悲觀鎖是針對并發(fā)的可能性比較大,而一般在我們的應(yīng)用中用樂觀鎖足以。

Oracle的悲觀鎖需要利用一條現(xiàn)有的連接,分成兩種方式,從SQL語句的區(qū)別來看,就是一種是for update,一種是for update nowait的形式。比如我們看一個(gè)例子。首先建立測試用的數(shù)據(jù)庫表。

CREATE TABLE TEST(ID,NAME,LOCATION,VALUE,CONSTRAINT test_pk PRIMARY KEY(ID))AS SELECT deptno, dname, loc, 1 FROM scott.dept

這里我們利用了Oracle的Sample的scott用戶的表,把數(shù)據(jù)copy到我們的test表中。首先我們看一下for update鎖定方式。首先我們執(zhí)行如下的select for update語句。

select * from test where id = 10 for update

通過這條檢索語句鎖定以后,再開另外一個(gè)sql*plus窗口進(jìn)行操作,再把上面這條sql語句執(zhí)行一便,你會發(fā)現(xiàn)sqlplus好像死在那里了,好像檢索不到數(shù)據(jù)的樣子,但是也不返回任何結(jié)果,就屬于卡在那里的感覺。這個(gè)時(shí)候是什么原因呢,就是一開始的第一個(gè)Session中的select for update語句把數(shù)據(jù)鎖定住了。由于這里鎖定的機(jī)制是wait的狀態(tài)(只要不表示nowait那就是wait),所以第二個(gè)Session(也就是卡住的那個(gè)sql*plus)中當(dāng)前這個(gè)檢索就處于等待狀態(tài)。當(dāng)?shù)谝粋€(gè)session最后commit或者rollback之后,第二個(gè)session中的檢索結(jié)果就是自動(dòng)跳出來,并且也把數(shù)據(jù)鎖定住。不過如果你第二個(gè)session中你的檢索語句如下所示。

select * from test where id = 10

也就是沒有for update這種鎖定數(shù)據(jù)的語句的話,就不會造成阻塞了。另外一種情況,就是當(dāng)數(shù)據(jù)庫數(shù)據(jù)被鎖定的時(shí)候,也就是執(zhí)行剛才for update那條sql以后,我們在另外一個(gè)session中執(zhí)行for update nowait后又是什么樣呢。比如如下的sql語句。 由于這條語句中是制定采用nowait方式來進(jìn)行檢索,所以當(dāng)發(fā)現(xiàn)數(shù)據(jù)被別的session鎖定中的時(shí)候,就會迅速返回ORA-00054錯(cuò)誤,內(nèi)容是資源正忙, 但指定以 NOWAIT 方式獲取資源。所以在程序中我們可以采用nowait方式迅速判斷當(dāng)前數(shù)據(jù)是否被鎖定中,如果鎖定中的話,就要采取相應(yīng)的業(yè)務(wù)措施進(jìn)行處理。

select * from test where id = 10 for update nowait

那這里另外一個(gè)問題,就是當(dāng)我們鎖定住數(shù)據(jù)的時(shí)候,我們對數(shù)據(jù)進(jìn)行更新和刪除的話會是什么樣呢。比如同樣,我們讓第一個(gè)Session鎖定住id=10的那條數(shù)據(jù),我們在第二個(gè)session中執(zhí)行如下語句。

update test set value=2 where id = 10

這個(gè)時(shí)候我們發(fā)現(xiàn)update語句就好像select for update語句一樣也停住卡在這里,當(dāng)你第一個(gè)session放開鎖定以后update才能正常運(yùn)行。當(dāng)你update運(yùn)行后,數(shù)據(jù)又被你update語句鎖定住了,這個(gè)時(shí)候只要你update后還沒有commit,別的session照樣不能對數(shù)據(jù)進(jìn)行鎖定更新等等。

總之,Oracle中的悲觀鎖就是利用Oracle的Connection對數(shù)據(jù)進(jìn)行鎖定。在Oracle中,用這種行級鎖帶來的性能損失是很小的,只是要注意程序邏輯,不要給你一不小心搞成死鎖了就好。而且由于數(shù)據(jù)的及時(shí)鎖定,在數(shù)據(jù)提交時(shí)候就不呼出現(xiàn)沖突,可以省去很多惱人的數(shù)據(jù)沖突處理。缺點(diǎn)就是你必須要始終有一條數(shù)據(jù)庫連接,就是說在整個(gè)鎖定到最后放開鎖的過程中,你的數(shù)據(jù)庫聯(lián)接要始終保持住。與悲觀鎖相對的,我們有了樂觀鎖。樂觀鎖一開始也說了,就是一開始假設(shè)不會造成數(shù)據(jù)沖突,在最后提交的時(shí)候再進(jìn)行數(shù)據(jù)沖突檢測。在樂觀鎖中,我們有3種

常用的做法來實(shí)現(xiàn)。

[1]第一種就是在數(shù)據(jù)取得的時(shí)候把整個(gè)數(shù)據(jù)都copy到應(yīng)用中,在進(jìn)行提交的時(shí)候比對當(dāng)前數(shù)據(jù)庫中的數(shù)據(jù)和開始的時(shí)候更新前取得的數(shù)據(jù)。當(dāng)發(fā)現(xiàn)兩個(gè)數(shù)據(jù)一模一樣以后,就表示沒有沖突可以提交,否則則是并發(fā)沖突,需要去用業(yè)務(wù)邏輯進(jìn)行解決。

[2]第二種樂觀鎖的做法就是采用版本戳,這個(gè)在Hibernate中得到了使用。采用版本戳的話,首先需要在你有樂觀鎖的數(shù)據(jù)庫table上建立一個(gè)新的column,比如為number型,當(dāng)你數(shù)據(jù)每更新一次的時(shí)候,版本數(shù)就會往上增加1。比如同樣有2個(gè)session同樣對某條數(shù)據(jù)進(jìn)行操作。兩者都取到當(dāng)前的數(shù)據(jù)的版本號為1,當(dāng)?shù)谝粋€(gè)session進(jìn)行數(shù)據(jù)更新后,在提交的時(shí)候查看到當(dāng)前數(shù)據(jù)的版本還為1,和自己一開始取到的版本相同。就正式提交,然后把版本號增加1,這個(gè)時(shí)候當(dāng)前數(shù)據(jù)的版本為2。當(dāng)?shù)诙€(gè)session也更新了數(shù)據(jù)提交的時(shí)候,發(fā)現(xiàn)數(shù)據(jù)庫中版本為2,和一開始這個(gè)session取到的版本號不一致,就知道別人更新過此條數(shù)據(jù),這個(gè)

時(shí)候再進(jìn)行業(yè)務(wù)處理,比如整個(gè)Transaction都Rollback等等操作。在用版本戳的時(shí)候,可以在應(yīng)用程序側(cè)使用版本戳的驗(yàn)證,也可以在數(shù)據(jù)庫側(cè)采用Trigger(觸發(fā)器)來進(jìn)行驗(yàn)證。不過數(shù)據(jù)庫的Trigger的性能開銷還是比較的大,所以能在應(yīng)用側(cè)進(jìn)行驗(yàn)證的話還是推薦不用Trigger。

[3]第三種做法和第二種做法有點(diǎn)類似,就是也新增一個(gè)Table的Column,不過這次這個(gè)column是采用timestamp型,存儲數(shù)據(jù)最后更新的時(shí)間。在Oracle9i以后可以采用新的數(shù)據(jù)類型,也就是timestamp with time zone類型來做時(shí)間戳。這種Timestamp的數(shù)據(jù)精度在Oracle的時(shí)間類型中是最高的,精確到微秒(還沒與到納秒的級別),一般來說,加上數(shù)據(jù)庫處理時(shí)間和人的思考動(dòng)作時(shí)間,微秒級別是非常非常夠了,其實(shí)只要精確到毫秒甚至秒都應(yīng)該沒有什么問題。和剛才的版本戳類似,也是在更新提交的時(shí)候檢查當(dāng)前數(shù)據(jù)庫中數(shù)據(jù)的時(shí)間戳和自己更新前取到的時(shí)間戳進(jìn)行對比,如果一致則OK,否則就是版本沖突。如果不想把代碼寫在程序中或者由于別的原因無法把代碼寫在現(xiàn)有的程序中,也可以把這個(gè)時(shí)間戳樂觀鎖邏輯寫在Trigger或者存儲過程中。

不知道這個(gè)是不是你需要的...

如何在SQLServer中鎖定某行記錄

可以用悲觀鎖和樂觀鎖兩種訪求

(1)悲觀鎖

就像前面所說的那樣使用

例如:

select * from ta with(UPDLOCK)

這樣當(dāng)記錄已經(jīng)被鎖定后,

其他的人再試圖再次更新訪問的時(shí)候會失敗。

詳細(xì)內(nèi)容不再細(xì)述了。

(2)樂觀鎖

類似16樓的說法,比如在表中增加一個(gè)字段以保存最后一次更新的時(shí)間戳,

更新的時(shí)候,用取得數(shù)據(jù)時(shí)的時(shí)間與數(shù)據(jù)庫中的更新時(shí)間進(jìn)行比較,

如果比數(shù)據(jù)庫中的最后更新時(shí)間早的話,

則說明之前已經(jīng)有其它人對于數(shù)據(jù)進(jìn)行了更新。

則更新不能進(jìn)行。

可以使用下面的語句進(jìn)行更新操作。

updata 表名 set ..... where upddate = 上次取得記錄的更新時(shí)間

sqlserver 在高并發(fā)的情況下 用什么事務(wù)隔離級別比較好

隔離級別越高,越能保證數(shù)據(jù)的完整性和一致性,但是對并發(fā)性能的影響也越大。

對于多數(shù)應(yīng)用程序,可以優(yōu)先考慮把數(shù)據(jù)庫系統(tǒng)的隔離級別設(shè)為Read Committed,它能夠避免臟讀取,而且具有較好的并發(fā)性能。

盡管它會導(dǎo)致不可重復(fù)讀、虛讀和第二類丟失更新這些并發(fā)問題,在可能出現(xiàn)這類問題的個(gè)別場合,可以由應(yīng)用程序采用悲觀鎖或樂觀鎖來控制。

sql server 怎么保證查詢出的結(jié)果不能被其他電腦訪問,具體如下

這涉及到數(shù)據(jù)庫中,鎖的概念

首先,SQL Server更強(qiáng)調(diào)由系統(tǒng)來管理鎖。在用戶有SQL請求時(shí),系統(tǒng)分析請求,自動(dòng)在滿足鎖定條件和系統(tǒng)性能之間為數(shù)據(jù)庫加上適當(dāng)?shù)逆i,同時(shí)系統(tǒng)在運(yùn)行期間常常自動(dòng)進(jìn)行優(yōu)化處理,實(shí)行動(dòng)態(tài)加鎖。也就是說,你的擔(dān)心是不必要的,SQLServer可以保證這種情況基本不會出現(xiàn).如果特殊情況下,需要你手動(dòng)出來,請參考下面文檔。

一. 為什么要引入鎖

多個(gè)用戶同時(shí)對數(shù)據(jù)庫的并發(fā)操作時(shí)會帶來以下數(shù)據(jù)不一致的問題:

丟失更新

A,B兩個(gè)用戶讀同一數(shù)據(jù)并進(jìn)行修改,其中一個(gè)用戶的修改結(jié)果破壞了另一個(gè)修改的結(jié)果,比如訂票系統(tǒng)

臟讀

A用戶修改了數(shù)據(jù),隨后B用戶又讀出該數(shù)據(jù),但A用戶因?yàn)槟承┰蛉∠藢?shù)據(jù)的修改,數(shù)據(jù)恢復(fù)原值,此時(shí)B得到的數(shù)據(jù)就與數(shù)據(jù)庫內(nèi)的數(shù)據(jù)產(chǎn)生了不一致

不可重復(fù)讀

A用戶讀取數(shù)據(jù),隨后B用戶讀出該數(shù)據(jù)并修改,此時(shí)A用戶再讀取數(shù)據(jù)時(shí)發(fā)現(xiàn)前后兩次的值不一致

并發(fā)控制的主要方法是封鎖,鎖就是在一段時(shí)間內(nèi)禁止用戶做某些操作以避免產(chǎn)生數(shù)據(jù)不一致

二 鎖的分類

鎖的類別有兩種分法:

1. 從數(shù)據(jù)庫系統(tǒng)的角度來看:分為獨(dú)占鎖(即排它鎖),共享鎖和更新鎖

MS-SQL Server 使用以下資源鎖模式。

鎖模式 描述

共享 (S) 用于不更改或不更新數(shù)據(jù)的操作(只讀操作),如 SELECT 語句。

更新 (U) 用于可更新的資源中。防止當(dāng)多個(gè)會話在讀取、鎖定以及隨后可能進(jìn)行的資源更新時(shí)發(fā)生常見形式的死鎖。

排它 (X) 用于數(shù)據(jù)修改操作,例如 INSERT、UPDATE 或 DELETE。確保不會同時(shí)同一資源進(jìn)行多重更新。

意向鎖 用于建立鎖的層次結(jié)構(gòu)。意向鎖的類型為:意向共享 (IS)、意向排它 (IX) 以及與意向排它共享 (SIX)。

架構(gòu)鎖 在執(zhí)行依賴于表架構(gòu)的操作時(shí)使用。架構(gòu)鎖的類型為:架構(gòu)修改 (Sch-M) 和架構(gòu)穩(wěn)定性 (Sch-S)。

大容量更新 (BU) 向表中大容量復(fù)制數(shù)據(jù)并指定了 TABLOCK 提示時(shí)使用。

共享鎖

共享 (S) 鎖允許并發(fā)事務(wù)讀取 (SELECT) 一個(gè)資源。資源上存在共享 (S) 鎖時(shí),任何其它事務(wù)都不能修改數(shù)據(jù)。一旦已經(jīng)讀取數(shù)據(jù),便立即釋放資源上的共享 (S) 鎖,除非將事務(wù)隔離級別設(shè)置為可重復(fù)讀或更高級別,或者在事務(wù)生存周期內(nèi)用鎖定提示保留共享 (S) 鎖。

更新鎖

更新 (U) 鎖可以防止通常形式的死鎖。一般更新模式由一個(gè)事務(wù)組成,此事務(wù)讀取記錄,獲取資源(頁或行)的共享 (S) 鎖,然后修改行,此操作要求鎖轉(zhuǎn)換為排它 (X) 鎖。如果兩個(gè)事務(wù)獲得了資源上的共享模式鎖,然后試圖同時(shí)更新數(shù)據(jù),則一個(gè)事務(wù)嘗試將鎖轉(zhuǎn)換為排它 (X) 鎖。共享模式到排它鎖的轉(zhuǎn)換必須等待一段時(shí)間,因?yàn)橐粋€(gè)事務(wù)的排它鎖與其它事務(wù)的共享模式鎖不兼容;發(fā)生鎖等待。第二個(gè)事務(wù)試圖獲取排它 (X) 鎖以進(jìn)行更新。由于兩個(gè)事務(wù)都要轉(zhuǎn)換為排它 (X) 鎖,并且每個(gè)事務(wù)都等待另一個(gè)事務(wù)釋放共享模式鎖,因此發(fā)生死鎖。

若要避免這種潛在的死鎖問題,請使用更新 (U) 鎖。一次只有一個(gè)事務(wù)可以獲得資源的更新 (U) 鎖。如果事務(wù)修改資源,則更新 (U) 鎖轉(zhuǎn)換為排它 (X) 鎖。否則,鎖轉(zhuǎn)換為共享鎖。

排它鎖

排它 (X) 鎖可以防止并發(fā)事務(wù)對資源進(jìn)行訪問。其它事務(wù)不能讀取或修改排它 (X) 鎖鎖定的數(shù)據(jù)。

意向鎖

意向鎖表示 SQL Server 需要在層次結(jié)構(gòu)中的某些底層資源上獲取共享 (S) 鎖或排它 (X) 鎖。例如,放置在表級的共享意向鎖表示事務(wù)打算在表中的頁或行上放置共享 (S) 鎖。在表級設(shè)置意向鎖可防止另一個(gè)事務(wù)隨后在包含那一頁的表上獲取排它 (X) 鎖。意向鎖可以提高性能,因?yàn)?SQL Server 僅在表級檢查意向鎖來確定事務(wù)是否可以安全地獲取該表上的鎖。而無須檢查表中的每行或每頁上的鎖以確定事務(wù)是否可以鎖定整個(gè)表。

意向鎖包括意向共享 (IS)、意向排它 (IX) 以及與意向排它共享 (SIX)。

鎖模式 描述

意向共享 (IS) 通過在各資源上放置 S 鎖,表明事務(wù)的意向是讀取層次結(jié)構(gòu)中的部分(而不是全部)底層資源。

意向排它 (IX) 通過在各資源上放置 X 鎖,表明事務(wù)的意向是修改層次結(jié)構(gòu)中的部分(而不是全部)底層資源。IX 是 IS 的超集。

與意向排它共享 (SIX) 通過在各資源上放置 IX 鎖,表明事務(wù)的意向是讀取層次結(jié)構(gòu)中的全部底層資源并修改部分(而不是全部)底層資源。允許頂層資源上的并發(fā) IS 鎖。例如,表的 SIX 鎖在表上放置一個(gè) SIX 鎖(允許并發(fā) IS 鎖),在當(dāng)前所修改頁上放置 IX 鎖(在已修改行上放置 X 鎖)。雖然每個(gè)資源在一段時(shí)間內(nèi)只能有一個(gè) SIX 鎖,以防止其它事務(wù)對資源進(jìn)行更新,但是其它事務(wù)可以通過獲取表級的 IS 鎖來讀取層次結(jié)構(gòu)中的底層資源。

獨(dú)占鎖:只允許進(jìn)行鎖定操作的程序使用,其他任何對他的操作均不會被接受。執(zhí)行數(shù)據(jù)更新命令時(shí),SQL Server會自動(dòng)使用獨(dú)占鎖。當(dāng)對象上有其他鎖存在時(shí),無法對其加獨(dú)占鎖。

共享鎖:共享鎖鎖定的資源可以被其他用戶讀取,但其他用戶無法修改它,在執(zhí)行Select時(shí),SQL Server會對對象加共享鎖。

更新鎖:當(dāng)SQL Server準(zhǔn)備更新數(shù)據(jù)時(shí),它首先對數(shù)據(jù)對象作更新鎖鎖定,這樣數(shù)據(jù)將不能被修改,但可以讀取。等到SQL Server確定要進(jìn)行更新數(shù)據(jù)操作時(shí),他會自動(dòng)將更新鎖換為獨(dú)占鎖,當(dāng)對象上有其他鎖存在時(shí),無法對其加更新鎖。

2. 從程序員的角度看:分為樂觀鎖和悲觀鎖。

樂觀鎖:完全依靠數(shù)據(jù)庫來管理鎖的工作。

悲觀鎖:程序員自己管理數(shù)據(jù)或?qū)ο笊系逆i處理。

MS-SQLSERVER 使用鎖在多個(gè)同時(shí)在數(shù)據(jù)庫內(nèi)執(zhí)行修改的用戶間實(shí)現(xiàn)悲觀并發(fā)控制

三 鎖的粒度

鎖粒度是被封鎖目標(biāo)的大小,封鎖粒度小則并發(fā)性高,但開銷大,封鎖粒度大則并發(fā)性低但開銷小

SQL Server支持的鎖粒度可以分為為行、頁、鍵、鍵范圍、索引、表或數(shù)據(jù)庫獲取鎖

資源 描述

RID 行標(biāo)識符。用于單獨(dú)鎖定表中的一行。

鍵 索引中的行鎖。用于保護(hù)可串行事務(wù)中的鍵范圍。

頁 8 千字節(jié) (KB) 的數(shù)據(jù)頁或索引頁。

擴(kuò)展盤區(qū) 相鄰的八個(gè)數(shù)據(jù)頁或索引頁構(gòu)成的一組。

表 包括所有數(shù)據(jù)和索引在內(nèi)的整個(gè)表。

DB 數(shù)據(jù)庫。

四 鎖定時(shí)間的長短

鎖保持的時(shí)間長度為保護(hù)所請求級別上的資源所需的時(shí)間長度。

用于保護(hù)讀取操作的共享鎖的保持時(shí)間取決于事務(wù)隔離級別。采用 READ COMMITTED 的默認(rèn)事務(wù)隔離級別時(shí),只在讀取頁的期間內(nèi)控制共享鎖。在掃描中,直到在掃描內(nèi)的下一頁上獲取鎖時(shí)才釋放鎖。如果指定 HOLDLOCK 提示或者將事務(wù)隔離級別設(shè)置為 REPEATABLE READ 或 SERIALIZABLE,則直到事務(wù)結(jié)束才釋放鎖。

根據(jù)為游標(biāo)設(shè)置的并發(fā)選項(xiàng),游標(biāo)可以獲取共享模式的滾動(dòng)鎖以保護(hù)提取。當(dāng)需要滾動(dòng)鎖時(shí),直到下一次提取或關(guān)閉游標(biāo)(以先發(fā)生者為準(zhǔn))時(shí)才釋放滾動(dòng)鎖。但是,如果指定 HOLDLOCK,則直到事務(wù)結(jié)束才釋放滾動(dòng)鎖。

用于保護(hù)更新的排它鎖將直到事務(wù)結(jié)束才釋放。

如果一個(gè)連接試圖獲取一個(gè)鎖,而該鎖與另一個(gè)連接所控制的鎖沖突,則試圖獲取鎖的連接將一直阻塞到:

將沖突鎖釋放而且連接獲取了所請求的鎖。

連接的超時(shí)間隔已到期。默認(rèn)情況下沒有超時(shí)間隔,但是一些應(yīng)用程序設(shè)置超時(shí)間隔以防止無限期等待

五 SQL Server 中鎖的自定義

1 處理死鎖和設(shè)置死鎖優(yōu)先級

死鎖就是多個(gè)用戶申請不同封鎖,由于申請者均擁有一部分封鎖權(quán)而又等待其他用戶擁有的部分封鎖而引起的無休止的等待

可以使用SET DEADLOCK_PRIORITY控制在發(fā)生死鎖情況時(shí)會話的反應(yīng)方式。如果兩個(gè)進(jìn)程都鎖定數(shù)據(jù),并且直到其它進(jìn)程釋放自己的鎖時(shí),每個(gè)進(jìn)程才能釋放自己的鎖,即發(fā)生死鎖情況。

2 處理超時(shí)和設(shè)置鎖超時(shí)持續(xù)時(shí)間。

@@LOCK_TIMEOUT 返回當(dāng)前會話的當(dāng)前鎖超時(shí)設(shè)置,單位為毫秒

SET LOCK_TIMEOUT 設(shè)置允許應(yīng)用程序設(shè)置語句等待阻塞資源的最長時(shí)間。當(dāng)語句等待的時(shí)間大于 LOCK_TIMEOUT 設(shè)置時(shí),系統(tǒng)將自動(dòng)取消阻塞的語句,并給應(yīng)用程序返回"已超過了鎖請求超時(shí)時(shí)段"的 1222 號錯(cuò)誤信息

示例

下例將鎖超時(shí)期限設(shè)置為 1,800 毫秒。

SET LOCK_TIMEOUT 1800

3) 設(shè)置事務(wù)隔離級別。

4 ) 對 SELECT、INSERT、UPDATE 和 DELETE 語句使用表級鎖定提示。

5) 配置索引的鎖定粒度

可以使用 sp_indexoption 系統(tǒng)存儲過程來設(shè)置用于索引的鎖定粒度

六 查看鎖的信息

1 執(zhí)行 EXEC SP_LOCK 報(bào)告有關(guān)鎖的信息

2 查詢分析器中按Ctrl+2可以看到鎖的信息

七 使用注意事項(xiàng)

如何避免死鎖

1 使用事務(wù)時(shí),盡量縮短事務(wù)的邏輯處理過程,及早提交或回滾事務(wù);

2 設(shè)置死鎖超時(shí)參數(shù)為合理范圍,如:3分鐘-10分種;超過時(shí)間,自動(dòng)放棄本次操作,避免進(jìn)程懸掛;

3 優(yōu)化程序,檢查并避免死鎖現(xiàn)象出現(xiàn);

4 .對所有的腳本和SP都要仔細(xì)測試,在正是版本之前。

5 所有的SP都要有錯(cuò)誤處理(通過@error)

6 一般不要修改SQL SERVER事務(wù)的默認(rèn)級別。不推薦強(qiáng)行加鎖

解決問題 如何對行 表 數(shù)據(jù)庫加鎖

八 幾個(gè)有關(guān)鎖的問題

1 如何鎖一個(gè)表的某一行

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

SELECT * FROM table ROWLOCK WHERE id = 1

2 鎖定數(shù)據(jù)庫的一個(gè)表

SELECT * FROM table WITH (HOLDLOCK)

加鎖語句:

sybase:

update 表 set col1=col1 where 1=0 ;

MSSQL:

select col1 from 表 (tablockx) where 1=0 ;

oracle:

LOCK TABLE 表 IN EXCLUSIVE MODE ;

加鎖后其它人不可操作,直到加鎖用戶解鎖,用commit或rollback解鎖

幾個(gè)例子幫助大家加深印象

設(shè)table1(A,B,C)

A B C

a1 b1 c1

a2 b2 c2

a3 b3 c3

1)排它鎖

新建兩個(gè)連接

在第一個(gè)連接中執(zhí)行以下語句

begin tran

update table1

set A='aa'

where B='b2'

waitfor delay '00:00:30' --等待30秒

commit tran

在第二個(gè)連接中執(zhí)行以下語句

begin tran

select * from table1

where B='b2'

commit tran

若同時(shí)執(zhí)行上述兩個(gè)語句,則select查詢必須等待update執(zhí)行完畢才能執(zhí)行即要等待30秒

2)共享鎖

在第一個(gè)連接中執(zhí)行以下語句

begin tran

select * from table1 holdlock -holdlock人為加鎖

where B='b2'

waitfor delay '00:00:30' --等待30秒

commit tran

在第二個(gè)連接中執(zhí)行以下語句

begin tran

select A,C from table1

where B='b2'

update table1

set A='aa'

where B='b2'

commit tran

若同時(shí)執(zhí)行上述兩個(gè)語句,則第二個(gè)連接中的select查詢可以執(zhí)行

而update必須等待第一個(gè)事務(wù)釋放共享鎖轉(zhuǎn)為排它鎖后才能執(zhí)行 即要等待30秒

3)死鎖

增設(shè)table2(D,E)

D E

d1 e1

d2 e2

在第一個(gè)連接中執(zhí)行以下語句

begin tran

update table1

set A='aa'

where B='b2'

waitfor delay '00:00:30'

update table2

set D='d5'

where E='e1'

commit tran

在第二個(gè)連接中執(zhí)行以下語句

begin tran

update table2

set D='d5'

where E='e1'

waitfor delay '00:00:10'

update table1

set A='aa'

where B='b2'

commit tran

同時(shí)執(zhí)行,系統(tǒng)會檢測出死鎖,并中止進(jìn)程

補(bǔ)充一點(diǎn):

Sql Server2000支持的表級鎖定提示

HOLDLOCK 持有共享鎖,直到整個(gè)事務(wù)完成,應(yīng)該在被鎖對象不需要時(shí)立即釋放,等于SERIALIZABLE事務(wù)隔離級別

NOLOCK 語句執(zhí)行時(shí)不發(fā)出共享鎖,允許臟讀 ,等于 READ UNCOMMITTED事務(wù)隔離級別

PAGLOCK 在使用一個(gè)表鎖的地方用多個(gè)頁鎖

READPAST 讓sql server跳過任何鎖定行,執(zhí)行事務(wù),適用于READ UNCOMMITTED事務(wù)隔離級別只跳過RID鎖,不跳過頁,區(qū)域和表鎖

ROWLOCK 強(qiáng)制使用行鎖

TABLOCKX 強(qiáng)制使用獨(dú)占表級鎖,這個(gè)鎖在事務(wù)期間阻止任何其他事務(wù)使用這個(gè)表

UPLOCK 強(qiáng)制在讀表時(shí)使用更新而不用共享鎖

應(yīng)用程序鎖:

應(yīng)用程序鎖就是客戶端代碼生成的鎖,而不是sql server本身生成的鎖

處理應(yīng)用程序鎖的兩個(gè)過程

sp_getapplock 鎖定應(yīng)用程序資源

sp_releaseapplock 為應(yīng)用程序資源解鎖

注意: 鎖定數(shù)據(jù)庫的一個(gè)表的區(qū)別

SELECT * FROM table WITH (HOLDLOCK) 其他事務(wù)可以讀取表,但不能更新刪除

SELECT * FROM table WITH (TABLOCKX) 其他事務(wù)不能讀取表,更新和刪除


網(wǎng)站題目:sqlserver悲觀鎖,sqlserver死鎖解決辦法
轉(zhuǎn)載注明:http://fisionsoft.com.cn/article/dsieepd.html