欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

sqlserver性能鎖,sqlserver高并發(fā)死鎖

如何處理SQL Server死鎖問題

死鎖,簡而言之,兩個(gè)或者多個(gè)trans,同時(shí)請(qǐng)求對(duì)方正在請(qǐng)求的某個(gè)對(duì)象,導(dǎo)致雙方互相等待。簡單的例子如下:

成都一家集口碑和實(shí)力的網(wǎng)站建設(shè)服務(wù)商,擁有專業(yè)的企業(yè)建站團(tuán)隊(duì)和靠譜的建站技術(shù),十年企業(yè)及個(gè)人網(wǎng)站建設(shè)經(jīng)驗(yàn) ,為成都數(shù)千家客戶提供網(wǎng)頁設(shè)計(jì)制作,網(wǎng)站開發(fā),企業(yè)網(wǎng)站制作建設(shè)等服務(wù),包括成都營銷型網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計(jì),同時(shí)也為不同行業(yè)的客戶提供網(wǎng)站建設(shè)、成都網(wǎng)站建設(shè)的服務(wù),包括成都電商型網(wǎng)站制作建設(shè),裝修行業(yè)網(wǎng)站制作建設(shè),傳統(tǒng)機(jī)械行業(yè)網(wǎng)站建設(shè),傳統(tǒng)農(nóng)業(yè)行業(yè)網(wǎng)站制作建設(shè)。在成都做網(wǎng)站,選網(wǎng)站制作建設(shè)服務(wù)商就選創(chuàng)新互聯(lián)建站。

trans1 trans2

------------------------------------------------------------------------

1.IDBConnection.BeginTransaction 1.IDBConnection.BeginTransaction

2.update table A 2.update table B

3.update table B 3.update table A

4.IDBConnection.Commit 4.IDBConnection.Commit

那么,很容易看到,如果trans1和trans2,分別到達(dá)了step3,那么trans1會(huì)請(qǐng)求對(duì)于B的X鎖,trans2會(huì)請(qǐng)求對(duì)于A的X鎖,而二者的鎖在step2上已經(jīng)被對(duì)方分別持有了。由于得不到鎖,后面的Commit無法執(zhí)行,這樣雙方開始死鎖。

好,我們看一個(gè)簡單的例子,來解釋一下,應(yīng)該如何解決死鎖問題。

-- Batch #1

CREATE DATABASE deadlocktest

GO

USE deadlocktest

SET NOCOUNT ON

DBCC TRACEON (1222, -1)

-- 在SQL2005中,增加了一個(gè)新的dbcc參數(shù),就是1222,原來在2000下,我們知道,可以執(zhí)行dbcc

--traceon(1204,3605,-1)看到所有的死鎖信息。SqlServer 2005中,對(duì)于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 = 1000) BEGIN

INSERT INTO t1 VALUES (@x*2, @x*2, @x*2, @x*2)

SET @x = @x + 1

END

GO

CREATE CLUSTERED INDEX cidx ON t1 (c1)

CREATE NONCLUSTERED INDEX idx1 ON t1 (c2)

GO

CREATE PROC p1 @p1 int AS SELECT c2, c3 FROM t1 WHERE c2 BETWEEN @p1 AND @p1+1

GO

CREATE PROC p2 @p1 int AS

UPDATE t1 SET c2 = c2+1 WHERE c1 = @p1

UPDATE t1 SET c2 = c2-1 WHERE c1 = @p1

GO

上述sql創(chuàng)建一個(gè)deadlock的示范數(shù)據(jù)庫,插入了1000條數(shù)據(jù),并在表t1上建立了c1列的聚集索引,和c2列的非聚集索引。另外創(chuàng)建了兩個(gè)sp,分別是從t1中select數(shù)據(jù)和update數(shù)據(jù)。

好,打開一個(gè)新的查詢窗口,我們開始執(zhí)行下面的query:

-- Batch #2

USE deadlocktest

SET NOCOUNT ON

WHILE (1=1) EXEC p2 4

GO

開始執(zhí)行后,然后我們打開第三個(gè)查詢窗口,執(zhí)行下面的query:

-- Batch #3

USE deadlocktest

SET NOCOUNT ON

CREATE TABLE #t1 (c2 int, c3 int)

GO

WHILE (1=1) BEGIN

INSERT INTO #t1 EXEC p1 4

TRUNCATE TABLE #t1

END

GO

開始執(zhí)行,哈哈,很快,我們看到了這樣的錯(cuò)誤信息:

Msg 1205, Level 13, State 51, Procedure p1, Line 4

Transaction (Process ID 54) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

spid54發(fā)現(xiàn)了死鎖。

那么,我們?cè)撊绾谓鉀Q它?

在SqlServer 2005中,我們可以這么做:

1.在trans3的窗口中,選擇EXEC p1 4,然后right click,看到了菜單了嗎?選擇Analyse Query in Database Engine Tuning Advisor。

2.注意右面的窗口中,wordload有三個(gè)選擇:負(fù)載文件、表、查詢語句,因?yàn)槲覀冞x擇了查詢語句的方式,所以就不需要修改這個(gè)radio option了。

3.點(diǎn)左上角的Start Analysis按鈕

4.抽根煙,回來后看結(jié)果吧!出現(xiàn)了一個(gè)分析結(jié)果窗口,其中,在Index Recommendations中,我們發(fā)現(xiàn)了一條信息:大意是,在表t1上增加一個(gè)非聚集索引索引:t2+t1。

5.在當(dāng)前窗口的上方菜單上,選擇Action菜單,選擇Apply Recommendations,系統(tǒng)會(huì)自動(dòng)創(chuàng)建這個(gè)索引。

重新運(yùn)行batch #3,呵呵,死鎖沒有了。

這種方式,我們可以解決大部分的Sql Server死鎖問題。那么,發(fā)生這個(gè)死鎖的根本原因是什么呢?為什么增加一個(gè)non clustered index,問題就解決了呢? 這次,我們分析一下,為什么會(huì)死鎖呢?再回顧一下兩個(gè)sp的寫法:

CREATE PROC p1 @p1 int AS

SELECT c2, c3 FROM t1 WHERE c2 BETWEEN @p1 AND @p1+1

GO

CREATE PROC p2 @p1 int AS

UPDATE t1 SET c2 = c2+1 WHERE c1 = @p1

UPDATE t1 SET c2 = c2-1 WHERE c1 = @p1

GO

很奇怪吧!p1沒有insert,沒有delete,沒有update,只是一個(gè)select,p2才是update。這個(gè)和我們前面說過的,trans1里面updata A,update B;trans2里面upate B,update A,根本不貼邊?。?/p>

那么,什么導(dǎo)致了死鎖?

需要從事件日志中,看sql的死鎖信息:

Spid X is running this query (line 2 of proc [p1], inputbuffer “… EXEC p1 4 …”):

SELECT c2, c3 FROM t1 WHERE c2 BETWEEN @p1 AND @p1+1

Spid Y is running this query (line 2 of proc [p2], inputbuffer “EXEC p2 4”):

UPDATE t1 SET c2 = c2+1 WHERE c1 = @p1

The SELECT is waiting for a Shared KEY lock on index t1.cidx. The UPDATE holds a conflicting X lock.

The UPDATE is waiting for an eXclusive KEY lock on index t1.idx1. The SELECT holds a conflicting S lock.

首先,我們看看p1的執(zhí)行計(jì)劃。怎么看呢?可以執(zhí)行set statistics profile on,這句就可以了。下面是p1的執(zhí)行計(jì)劃

SELECT c2, c3 FROM t1 WHERE c2 BETWEEN @p1 AND @p1+1

|--Nested Loops(Inner Join, OUTER REFERENCES:([Uniq1002], [t1].[c1]))

|--Index Seek(OBJECT:([t1].[idx1]), SEEK:([t1].[c2] = [@p1] AND [t1].[c2] = [@p1]+(1)) ORDERED FORWARD)

|--Clustered Index Seek(OBJECT:([t1].[cidx]), SEEK:([t1].[c1]=[t1].[c1] AND [Uniq1002]=[Uniq1002]) LOOKUP ORDERED FORWARD)

我們看到了一個(gè)nested loops,第一行,利用索引t1.c2來進(jìn)行seek,seek出來的那個(gè)rowid,在第二行中,用來通過聚集索引來查找整行的數(shù)據(jù)。這是什么?就是bookmark lookup啊!為什么?因?yàn)槲覀冃枰腸2、c3不能完全的被索引t1.c1帶出來,所以需要書簽查找。

好,我們接著看p2的執(zhí)行計(jì)劃。

UPDATE t1 SET c2 = c2+1 WHERE c1 = @p1

|--Clustered Index Update(OBJECT:([t1].[cidx]), OBJECT:([t1].[idx1]), SET:([t1].[c2] = [Expr1004]))

|--Compute Scalar(DEFINE:([Expr1013]=[Expr1013]))

|--Compute Scalar(DEFINE:([Expr1004]=[t1].[c2]+(1), [Expr1013]=CASE WHEN CASE WHEN ...

|--Top(ROWCOUNT est 0)

|--Clustered Index Seek(OBJECT:([t1].[cidx]), SEEK:([t1].[c1]=[@p1]) ORDERED FORWARD)

通過聚集索引的seek找到了一行,然后開始更新。這里注意的是,update的時(shí)候,它會(huì)申請(qǐng)一個(gè)針對(duì)clustered index的X鎖的。

實(shí)際上到這里,我們就明白了為什么update會(huì)對(duì)select產(chǎn)生死鎖。update的時(shí)候,會(huì)申請(qǐng)一個(gè)針對(duì)clustered index的X鎖,這樣就阻塞住了(注意,不是死鎖?。﹕elect里面最后的那個(gè)clustered index seek。死鎖的另一半在哪里呢?注意我們的select語句,c2存在于索引idx1中,c1是一個(gè)聚集索引cidx。問題就在這里!我們?cè)趐2中更新了c2這個(gè)值,所以sqlserver會(huì)自動(dòng)更新包含c2列的非聚集索引:idx1。而idx1在哪里?就在我們剛才的select語句中。而對(duì)這個(gè)索引列的更改,意味著索引集合的某個(gè)行或者某些行,需要重新排列,而重新排列,需要一個(gè)X鎖。

SO………,問題就這樣被發(fā)現(xiàn)了。

總結(jié)一下,就是說,某個(gè)query使用非聚集索引來select數(shù)據(jù),那么它會(huì)在非聚集索引上持有一個(gè)S鎖。當(dāng)有一些select的列不在該索引上,它需要根據(jù)rowid找到對(duì)應(yīng)的聚集索引的那行,然后找到其他數(shù)據(jù)。而此時(shí),第二個(gè)的查詢中,update正在聚集索引上忙乎:定位、加鎖、修改等。但因?yàn)檎谛薷牡哪硞€(gè)列,是另外一個(gè)非聚集索引的某個(gè)列,所以此時(shí),它需要同時(shí)更改那個(gè)非聚集索引的信息,這就需要在那個(gè)非聚集索引上,加第二個(gè)X鎖。select開始等待update的X鎖,update開始等待select的S鎖,死鎖,就這樣發(fā)生鳥。

那么,為什么我們?cè)黾恿艘粋€(gè)非聚集索引,死鎖就消失鳥?我們看一下,按照上文中自動(dòng)增加的索引之后的執(zhí)行計(jì)劃:

SELECT c2, c3 FROM t1 WHERE c2 BETWEEN @p1 AND @p1+1

|--Index Seek(OBJECT:([deadlocktest].[dbo].[t1].[_dta_index_t1_7_2073058421__K2_K1_3]), SEEK:([deadlocktest].[dbo].[t1].[c2] = [@p1] AND [deadlocktest].[dbo].[t1].[c2] = [@p1]+(1)) ORDERED FORWARD)

哦,對(duì)于clustered index的需求沒有了,因?yàn)樵黾拥母采w索引已經(jīng)足夠把所有的信息都select出來。就這么簡單。

實(shí)際上,在sqlserver 2005中,如果用profiler來抓eventid:1222,那么會(huì)出現(xiàn)一個(gè)死鎖的圖,很直觀的說。

下面的方法,有助于將死鎖減至最少(詳細(xì)情況,請(qǐng)看SQLServer聯(lián)機(jī)幫助,搜索:將死鎖減至最少即可。

按同一順序訪問對(duì)象。

避免事務(wù)中的用戶交互。

保持事務(wù)簡短并處于一個(gè)批處理中。

使用較低的隔離級(jí)別。

使用基于行版本控制的隔離級(jí)別。

將 READ_COMMITTED_SNAPSHOT 數(shù)據(jù)庫選項(xiàng)設(shè)置為 ON,使得已提交讀事務(wù)使用行版本控制。

使用快照隔離。

使用綁定連接。

如何掌握SQLServer的鎖機(jī)制

SQL SERVER里的鎖機(jī)制:

NOLOCK(不加鎖)

此選項(xiàng)被選中時(shí),SQL Server 在讀取或修改數(shù)據(jù)時(shí)不加任何鎖。 在這種情況下,用戶有可能讀取到未完成事務(wù)(Uncommited Transaction)或回滾(Roll Back)中的數(shù)據(jù), 即所謂的“臟數(shù)據(jù)”。

HOLDLOCK(保持鎖)

此選項(xiàng)被選中時(shí),SQL Server 會(huì)將此共享鎖保持至整個(gè)事務(wù)結(jié)束,而不會(huì)在途中釋放。 例如,“ SELECT * FROM my_table HOLDLOCK”就要求在整個(gè)查詢過程中,保持對(duì)表的鎖定,直到查詢完成才釋放鎖定。

UPDLOCK(修改鎖)

此選項(xiàng)被選中時(shí),SQL Server 在讀取數(shù)據(jù)時(shí)使用修改鎖來代替共享鎖,并將此鎖保持至整個(gè)事務(wù)或命令結(jié)束。使用此選項(xiàng)能夠保證多個(gè)進(jìn)程能同時(shí)讀取數(shù)據(jù)但只有該進(jìn)程能修改數(shù)據(jù)。

TABLOCK(表鎖)

此選項(xiàng)被選中時(shí),SQL Server 將在整個(gè)表上置共享鎖直至該命令結(jié)束。 這個(gè)選項(xiàng)保證其他進(jìn)程只能讀取而不能修改數(shù)據(jù)。

PAGLOCK(頁鎖)

此選項(xiàng)為默認(rèn)選項(xiàng), 當(dāng)被選中時(shí),SQL Server 使用共享頁鎖。

TABLOCKX(排它表鎖)

此選項(xiàng)被選中時(shí),SQL Server 將在整個(gè)表上置排它鎖直至該命令或事務(wù)結(jié)束。這將防止其他進(jìn)程讀取或修改表中的數(shù)據(jù)。

sqlserver鎖表機(jī)制

這個(gè)問題要具體分析:

第一,事務(wù)隔離級(jí)別基本兩種模式,一種是阻塞式(read committed,repeatable read,serializable)

,一種是非阻塞式(read uncommitted,snapshot)。

默認(rèn)是read committed,這種情況一般在更新表的時(shí)候,如果不使用hint 提示,基本是先對(duì)表添加IX鎖,級(jí)別不算高,基本和其他鎖兼容,但是repeatable read,serializable 事務(wù)隔離級(jí)別就會(huì)先對(duì)表添加IX鎖,然后向X鎖轉(zhuǎn)化,而X鎖和大多數(shù)鎖都不兼容,容易發(fā)生表阻塞。

第二種隔離級(jí)別不會(huì)有以上問題,但是又引入了其它的問題。

以上是一種情況。

另外一種就是 鎖升級(jí),一個(gè)鎖是96B內(nèi)存,如果太多,sqlserver就會(huì)升級(jí)為表鎖,一般是5000以上行級(jí)鎖就升級(jí)為一個(gè)表X鎖。

所以適當(dāng)?shù)奈募纸M和表分區(qū) 是有必要的。

其次就是資源互相引用導(dǎo)致事務(wù)長時(shí)間不能釋放,導(dǎo)致真正的死鎖,不過SQL2005以后,這種情況發(fā)生的概率很低。

留個(gè)問題你自己去想。

兩個(gè)SQL,兩個(gè)連接,同時(shí)執(zhí)行。

update A set A.NAME=xxx where A.id=55

update A set A.NAME=xxx where A.id=56, 如果 56 不存在你說會(huì)發(fā)生什么情況呢?

如何監(jiān)控sqlserver 性能 死鎖

具體步驟如下:

1.首先使用下面的命令,將有關(guān)的跟蹤標(biāo)志啟用。

SQL codeDBCC TRACEON (3605,1204,1222,-1)

說明:

3605

將DBCC的結(jié)果輸出到錯(cuò)誤日志。

1204 返回參與死鎖的鎖的資源和類型,以及受影響的當(dāng)前命令。

1222

返回參與死鎖的鎖的資源和類型,以及使用了不符合任何 XSD 架構(gòu)的 XML 格式的受影響的當(dāng)前命令(比1204更進(jìn)一步,SQL

2005及以上可用)。

-1 以全局方式打開指定的跟蹤標(biāo)記。

以上跟蹤標(biāo)志作用域都是全局,即在SQL

Server運(yùn)行過程中,會(huì)一直發(fā)揮作用,直到SQL Server重啟。

如 果要確保SQL Server在重啟后自動(dòng)開啟這些標(biāo)志,可以在SQL

Server服務(wù)啟動(dòng)選項(xiàng)中,使用 /T 啟動(dòng)選項(xiàng)指定跟蹤標(biāo)志在啟動(dòng)期

間設(shè)置為開。(位于SQL Server配置管理器-SQL

Server服務(wù)-SQL Server-屬性-高級(jí)-啟動(dòng)參數(shù))

在運(yùn)行上面的語句后,當(dāng)SQL

Server中發(fā)生死鎖時(shí),已經(jīng)可以在錯(cuò)誤日志中看到了,但還不夠直觀(和其它信息混在一起)。(SSMS

- SQL Server實(shí)例 -

管理 - SQL Server日志)

2.建表,存放死鎖記錄

SQL codeUSE [Cole] --Cole是我的示例數(shù)據(jù)庫,你可以根據(jù)實(shí)際情況修改。 GO

CREATE TABLE DeadLockLog ( id int IDENTITY (1, 1) NOT NULL, LogDate DATETIME, ProcessInfo VARCHAR(10), ErrorText VARCHAR(MAX) )

GO

3.建立JOB

新建一個(gè)JOB(假設(shè)名稱為DeadLockJob),在"步驟"中新建一步驟,隨便寫一個(gè)步驟名稱,數(shù)據(jù)庫為"Cole",在"命令"欄中輸入以下語句:

SQL code--新建臨時(shí)表 IF OBJECT_ID('tempdb.dbo.#ErrorLog') IS Not Null

DROP TABLE #ErrorLog

CREATE TABLE #ErrorLog (Id int IDENTITY (1, 1) NOT NULL, a DATETIME, b VARCHAR(10), c VARCHAR(MAX)) --將當(dāng)前日志記錄插入臨時(shí)表

INSERT INTO #ErrorLog EXEC master.dbo.sp_readerrorlog --將死鎖信息插入用戶表

insert DeadLockLog

select a, b, c from #ErrorLog where id = (select MAX(id) from #ErrorLog WHERE c Like '%Deadlock encountered%')

DROP TABLE #ErrorLog

4.新建警報(bào)

在"新建警報(bào)"窗體的"常規(guī)"選項(xiàng)卡中,進(jìn)行以下設(shè)置:

名稱:可根據(jù)實(shí)際自行命名,這里我用DeadLockAlert

類型:選擇"SQL

Server性能條件警報(bào)"

對(duì)象:SQLServer:Locks

計(jì)數(shù)器:Number of

Deadlocks/sec

實(shí)例:_Total

計(jì)數(shù)器滿足以下條件時(shí)觸發(fā)警報(bào):高于

值:0

在"響應(yīng)"選項(xiàng)卡中,選中"執(zhí)行作業(yè)",并選擇步驟3中我們新建的作業(yè)(即DeadlockJob)

到這里為止,我們已經(jīng)完成了全部步驟,以后,你就可以隨時(shí)查詢DeadLockLog表,來顯示死鎖信息了。

sqlserver 線程鎖死怎么辦

T1、T2表示兩個(gè)任務(wù);R1和R2表示兩個(gè)資源;由資源指向任務(wù)的箭頭(如R1-T1,R2-T2)表示該資源被改任務(wù)所持有;由任務(wù)指向資源的箭頭(如T1-S2,T2-S1)表示該任務(wù)正在請(qǐng)求對(duì)應(yīng)目標(biāo)資源;

其滿足上面死鎖的四個(gè)必要條件:

(1).互斥:資源S1和S2不能被共享,同一時(shí)間只能由一個(gè)任務(wù)使用;

(2).請(qǐng)求與保持條件:T1持有S1的同時(shí),請(qǐng)求S2;T2持有S2的同時(shí)請(qǐng)求S1;

(3).非剝奪條件:T1無法從T2上剝奪S2,T2也無法從T1上剝奪S1;

(4).循環(huán)等待條件:上圖中的箭頭構(gòu)成環(huán)路,存在循環(huán)等待。

解析:如何快速掌握SQLServer的鎖機(jī)制

各種大型數(shù)據(jù)庫所采用的鎖的基本理論是一致的,但在具體實(shí)現(xiàn)上各有差別。SQLServer更強(qiáng)調(diào)由系統(tǒng)來管理鎖。在用戶有SQL請(qǐng)求時(shí),系統(tǒng)分析請(qǐ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)加鎖。對(duì)于一般的用戶而言,通過系統(tǒng)的自動(dòng)鎖定管理機(jī)制基本可以滿足使用要求,但如果對(duì)數(shù)據(jù)安全、數(shù)據(jù)庫完整性和一致性有特殊要求,就需要了解SQLServer的鎖機(jī)制,掌握數(shù)據(jù)庫鎖定方法。 鎖是數(shù)據(jù)庫中的一個(gè)非常重要的概念,它主要用于多用戶環(huán)境下保證數(shù)據(jù)庫完整性和一致性。我們知道,多個(gè)用戶能夠同時(shí)操縱同一個(gè)數(shù)據(jù)庫中的數(shù)據(jù),會(huì)發(fā)生數(shù)據(jù)不一致現(xiàn)象。即如果沒有鎖定且多個(gè)用戶同時(shí)訪問一個(gè)數(shù)據(jù)庫,則當(dāng)他們的事務(wù)同時(shí)使用相同的數(shù)據(jù)時(shí)可能會(huì)發(fā)生問題。這些問題包括:丟失更新、臟讀、不可重復(fù)讀和幻覺讀: 1.當(dāng)兩個(gè)或多個(gè)事務(wù)選擇同一行,然后基于最初選定的值更新該行時(shí),會(huì)發(fā)生丟失更新問題。每個(gè)事務(wù)都不知道其它事務(wù)的存在。最后的更新將重寫由其它事務(wù)所做的更新,這將導(dǎo)致數(shù)據(jù)丟失。例如,兩個(gè)編輯人員制作了同一文檔的電子復(fù)本。每個(gè)編輯人員獨(dú)立地更改其復(fù)本,然后保存更改后的復(fù)本,這樣就覆蓋了原始文檔。最后保存其更改復(fù)本的編輯人員覆蓋了第一個(gè)編輯人員所做的更改。如果在第一個(gè)編輯人員完成之后第二個(gè)編輯人員才能進(jìn)行更改,則可以避免該問題。 2.臟讀就是指當(dāng)一個(gè)事務(wù)正在訪問數(shù)據(jù),并且對(duì)數(shù)據(jù)進(jìn)行了修改,而這種修改還沒有提交到數(shù)據(jù)庫中,這時(shí),另外一個(gè)事務(wù)也訪問這個(gè)數(shù)據(jù),然后使用了這個(gè)數(shù)據(jù)。因?yàn)檫@個(gè)數(shù)據(jù)是還沒有提交的數(shù)據(jù),那么另外一個(gè)事務(wù)讀到的這個(gè)數(shù)據(jù)是臟數(shù)據(jù),依據(jù)臟數(shù)據(jù)所做的操作可能是不正確的。例如,一個(gè)編輯人員正在更改電子文檔。在更改過程中,另一個(gè)編輯人員復(fù)制了該文檔(該復(fù)本包含到目前為止所做的全部更改)并將其分發(fā)給預(yù)期的用戶。此后,第一個(gè)編輯人員認(rèn)為目前所做的更改是錯(cuò)誤的,于是刪除了所做的編輯并保存了文檔。分發(fā)給用戶的文檔包含不再存在的編輯內(nèi)容,并且這些編輯內(nèi)容應(yīng)認(rèn)為從未存在過。如果在第一個(gè)編輯人員確定最終更改前任何人都不能讀取更改的文檔,則可以避免該問題。 3.不可重復(fù)讀是指在一個(gè)事務(wù)內(nèi),多次讀同一數(shù)據(jù)。在這個(gè)事務(wù)還沒有結(jié)束時(shí),另外一個(gè)事務(wù)也訪問該同一數(shù)據(jù)。那么,在第一個(gè)事務(wù)中的兩次讀數(shù)據(jù)之間,由于第二個(gè)事務(wù)的修改,那么第一個(gè)事務(wù)兩次讀到的的數(shù)據(jù)可能是不一樣的。這樣就發(fā)生了在一個(gè)事務(wù)內(nèi)兩次讀到的數(shù)據(jù)是不一樣的,因此稱為是不可重復(fù)讀。例如,一個(gè)編輯人員兩次讀取同一文檔,但在兩次讀取之間,作者重寫了該文檔。當(dāng)編輯人員第二次讀取文檔時(shí),文檔已更改。原始讀取不可重復(fù)。如果只有在作者全部完成編寫后編輯人員才可以讀取文檔,則可以避免該問題。 4.幻覺讀是指當(dāng)事務(wù)不是獨(dú)立執(zhí)行時(shí)發(fā)生的一種現(xiàn)象,例如第一個(gè)事務(wù)對(duì)一個(gè)表中的數(shù)據(jù)進(jìn)行了修改,這種修改涉及到表中的全部數(shù)據(jù)行。同時(shí),第二個(gè)事務(wù)也修改這個(gè)表中的數(shù)據(jù),這種修改是向表中插入一行新數(shù)據(jù)。那么,以后就會(huì)發(fā)生操作第一個(gè)事務(wù)的用戶發(fā)現(xiàn)表中還有沒有修改的數(shù)據(jù)行,就好象發(fā)生了幻覺一樣。例如,一個(gè)編輯人員更改作者提交的文檔,但當(dāng)生產(chǎn)部門將其更改內(nèi)容合并到該文檔的主復(fù)本時(shí),發(fā)現(xiàn)作者已將未編輯的新材料添加到該文檔中。如果在編輯人員和生產(chǎn)部門完成對(duì)原始文檔的處理之前,任何人都不能將新材料添加到文檔中,則可以避免該問題。 所以,處理多用戶并發(fā)訪問的方法是加鎖。鎖是防止其他事務(wù)訪問指定的資源控制、實(shí)現(xiàn)并發(fā)控制的一種主要手段。當(dāng)一個(gè)用戶鎖住數(shù)據(jù)庫中的某個(gè)對(duì)象時(shí),其他用戶就不能再訪問該對(duì)象。加鎖對(duì)并發(fā)訪問的影響體現(xiàn)在鎖的粒度上。為了控制鎖定的資源,應(yīng)該首先了解系統(tǒng)的空間管理。在SQLServer2000系統(tǒng)中,最小的空間管理單位是頁,一個(gè)頁有8K。所有的數(shù)據(jù)、日志、索引都存放在頁上。另外,使用頁有一個(gè)限制,這就是表中的一行數(shù)據(jù)必須在同一個(gè)頁上,不能跨頁。頁上面的空間管理單位是盤區(qū),一個(gè)盤區(qū)是8個(gè)連續(xù)的頁。表和索引的最小占用單位是盤區(qū)。數(shù)據(jù)庫是由一個(gè)或者多個(gè)表或者索引組成,即是由多個(gè)盤區(qū)組成。放在一個(gè)表上的鎖限制對(duì)整個(gè)表的并發(fā)訪問;放在盤區(qū)上的鎖限制了對(duì)整個(gè)盤區(qū)的訪問;放在數(shù)據(jù)頁上的鎖限制了對(duì)整個(gè)數(shù)據(jù)頁的訪問;放在行上的鎖只限制對(duì)該行的并發(fā)訪問。 SQLServer2000具有多粒度鎖定,允許一個(gè)事務(wù)鎖定不同類型的的資源。為了使鎖定的成本減至最少,SQLServer自動(dòng)將資源鎖定在適合任務(wù)的級(jí)別。鎖定在較小的粒度(例如行)可以增加并發(fā)但需要較大的開銷,因?yàn)槿绻i定了許多行,則需要控制更多的鎖。鎖定在較大的粒度(例如表)就并發(fā)而言是相當(dāng)昂貴的,因?yàn)殒i定整個(gè)表限制了其它事務(wù)對(duì)表中任意部分進(jìn)行訪問,但要求的開銷較低,因?yàn)樾枰S護(hù)的鎖較少。SQLServer可以鎖定行、頁、擴(kuò)展盤區(qū)、表、庫等資源。 行是可以鎖定的最小空間,行級(jí)鎖占用的數(shù)據(jù)資源最少,所以在事務(wù)的處理過程中,允許其他事務(wù)繼續(xù)操縱同一個(gè)表或者同一個(gè)頁的其他數(shù)據(jù),大大降低了其他事務(wù)等待處理的時(shí)間,提高了系統(tǒng)的并發(fā)性。 頁級(jí)鎖是指在事務(wù)的操縱過程中,無論事務(wù)處理數(shù)據(jù)的多少,每一次都鎖定一頁,在這個(gè)頁上的數(shù)據(jù)不能被其他事務(wù)操縱。在SQLServer7.0以前,使用的是頁級(jí)鎖。頁級(jí)鎖鎖定的資源比行級(jí)鎖鎖定的數(shù)據(jù)資源多。在頁級(jí)鎖中,即使是一個(gè)事務(wù)只操縱頁上的一行數(shù)據(jù),那么該頁上的其他數(shù)據(jù)行也不能被其他事務(wù)使用。因此,當(dāng)使用頁級(jí)鎖時(shí),會(huì)出現(xiàn)數(shù)據(jù)的浪費(fèi)現(xiàn)象,也就是說,在同一個(gè)頁上會(huì)出現(xiàn)數(shù)據(jù)被占用卻沒有使用的現(xiàn)象。在這種現(xiàn)象中,數(shù)據(jù)的浪費(fèi)最多不超過一個(gè)頁上的數(shù)據(jù)行。 表級(jí)鎖也是一個(gè)非常重要的鎖。表級(jí)鎖是指事務(wù)在操縱某一個(gè)表的數(shù)據(jù)時(shí),鎖定了這個(gè)數(shù)據(jù)所在的整個(gè)表,其他事務(wù)不能訪問該表中的其他數(shù)據(jù)。當(dāng)事務(wù)處理的數(shù)據(jù)量比較大時(shí),一般使用表級(jí)鎖。表級(jí)鎖的特點(diǎn)是使用比較少的系統(tǒng)資源,但是卻占用比較多的數(shù)據(jù)資源。與行級(jí)鎖和頁級(jí)鎖相比,表級(jí)鎖占用的系統(tǒng)資源例如內(nèi)存比較少,但是占用的數(shù)據(jù)資源卻是最大。在表級(jí)鎖時(shí),有可能出現(xiàn)數(shù)據(jù)的大量浪費(fèi)現(xiàn)象,因?yàn)楸砑?jí)鎖鎖定整個(gè)表,那么其他的事務(wù)都不能操縱表中的其他數(shù)據(jù)。 盤區(qū)鎖是一種特殊類型的鎖,只能用在一些特殊的情況下。簇級(jí)鎖就是指事務(wù)占用一個(gè)盤區(qū),這個(gè)盤區(qū)不能同時(shí)被其他事務(wù)占用。例如在創(chuàng)建數(shù)據(jù)庫和創(chuàng)建表時(shí),系統(tǒng)分配物理空間時(shí)使用這種類型的鎖。系統(tǒng)是按照盤區(qū)分配空間的。當(dāng)系統(tǒng)分配空間時(shí),使用盤區(qū)鎖,防止其他事務(wù)同時(shí)使用同一個(gè)盤區(qū)。當(dāng)系統(tǒng)完成分配空間之后,就不再使用這種類型的盤區(qū)鎖。特別是,當(dāng)涉及到對(duì)數(shù)據(jù)操作的事務(wù)時(shí),不使用盤區(qū)鎖。 數(shù)據(jù)庫級(jí)鎖是指鎖定整個(gè)數(shù)據(jù)庫,防止任何用戶或者事務(wù)對(duì)鎖定的數(shù)據(jù)庫進(jìn)行訪問。數(shù)據(jù)庫級(jí)鎖是一種非常特殊的鎖,它只是用于數(shù)據(jù)庫的恢復(fù)操作過程中。這種等級(jí)的鎖是一種最高等級(jí)的鎖,因?yàn)樗刂普麄€(gè)數(shù)據(jù)庫的操作。只要對(duì)數(shù)據(jù)庫進(jìn)行恢復(fù)操作,那么就需要設(shè)置數(shù)據(jù)庫為單用戶模式,這樣系統(tǒng)就能防止其他用戶對(duì)該數(shù)據(jù)庫進(jìn)行各種操作。 行級(jí)鎖是一種最優(yōu)鎖,因?yàn)樾屑?jí)鎖不可能出現(xiàn)數(shù)據(jù)既被占用又沒有使用的浪費(fèi)現(xiàn)象。但是,如果用戶事務(wù)中頻繁對(duì)某個(gè)表中的多條記錄操作,將導(dǎo)致對(duì)該表的許多記錄行都加上了行級(jí)鎖,數(shù)據(jù)庫系統(tǒng)中鎖的數(shù)目會(huì)急劇增加,這樣就加重了系統(tǒng)負(fù)荷,影響系統(tǒng)性能。因此,在SQLServer中,還支持鎖升級(jí)(lockescalation)。所謂鎖升級(jí)是指調(diào)整鎖的粒度,將多個(gè)低粒度的鎖替換成少數(shù)的更高粒度的鎖,以此來降低系統(tǒng)負(fù)荷。在SQLServer中當(dāng)一個(gè)事務(wù)中的鎖較多,達(dá)到鎖升級(jí)門限時(shí),系統(tǒng)自動(dòng)將行級(jí)鎖和頁面鎖升級(jí)為表級(jí)鎖。

當(dāng)前名稱:sqlserver性能鎖,sqlserver高并發(fā)死鎖
鏈接地址:http://chinadenli.net/article28/hddhjp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站收錄定制網(wǎng)站、微信公眾號(hào)網(wǎng)站維護(hù)、自適應(yīng)網(wǎng)站、品牌網(wǎng)站設(shè)計(jì)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)