国产99久久精品_欧美日本韩国一区二区_激情小说综合网_欧美一级二级视频_午夜av电影_日本久久精品视频

最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
當(dāng)前位置: 首頁 - 科技 - 知識百科 - 正文

SQLServer數(shù)據(jù)庫死鎖原因與解決辦法

來源:懂視網(wǎng) 責(zé)編:小采 時間:2020-11-09 09:59:25
文檔

SQLServer數(shù)據(jù)庫死鎖原因與解決辦法

SQLServer數(shù)據(jù)庫死鎖原因與解決辦法:SQL Server數(shù)據(jù)庫死鎖,通俗的講就是兩個或多個trans,同時請求對方正在請求的某個實際應(yīng)用對象,而導(dǎo)致雙方互相等待。簡單的例子如下: sql server死鎖表現(xiàn)一: 一個用戶A 訪問表A(鎖住了表A),然后又訪問表B 另一個用戶B 訪問表B(鎖住了表B),然后企
推薦度:
導(dǎo)讀SQLServer數(shù)據(jù)庫死鎖原因與解決辦法:SQL Server數(shù)據(jù)庫死鎖,通俗的講就是兩個或多個trans,同時請求對方正在請求的某個實際應(yīng)用對象,而導(dǎo)致雙方互相等待。簡單的例子如下: sql server死鎖表現(xiàn)一: 一個用戶A 訪問表A(鎖住了表A),然后又訪問表B 另一個用戶B 訪問表B(鎖住了表B),然后企

SQL Server數(shù)據(jù)庫死鎖,通俗的講就是兩個或多個trans,同時請求對方正在請求的某個實際應(yīng)用對象,而導(dǎo)致雙方互相等待。簡單的例子如下:

sql server死鎖表現(xiàn)一:

   一個用戶A 訪問表A(鎖住了表A),然后又訪問表B
   另一個用戶B 訪問表B(鎖住了表B),然后企圖訪問表A
   這時用戶A由于用戶B已經(jīng)鎖住表B,它必須等待用戶B釋放表B,才能繼續(xù),好了他老人家就只好老老實實在這等了
   同樣用戶B要等用戶A釋放表A才能繼續(xù)這就死鎖了
  sql server死鎖解決方法:
   這種死鎖是由于你的程序的BUG產(chǎn)生的,除了調(diào)整你的程序的邏輯別無他法
   仔細(xì)分析你程序的邏輯,
   1:盡量避免同時鎖定兩個資源
   2: 必須同時鎖定兩個資源時,要保證在任何時刻都應(yīng)該按照相同的順序來鎖定資源.
  
sql server死鎖表現(xiàn)二:

   用戶A讀一條紀(jì)錄,然后修改該條紀(jì)錄
   這是用戶B修改該條紀(jì)錄
   這里用戶A的事務(wù)里鎖的性質(zhì)由共享鎖企圖上升到獨占鎖(for update),而用戶B里的獨占鎖由于A有共享鎖存在所

以必須等A釋
  放掉共享鎖,而A由于B的獨占鎖而無法上升的獨占鎖也就不可能釋放共享鎖,于是出現(xiàn)了死鎖。
   這種死鎖比較隱蔽,但其實在稍大點的項目中經(jīng)常發(fā)生。
  sql server死鎖解決方法:
   讓用戶A的事務(wù)(即先讀后寫類型的操作),在select 時就是用Update lock
語法如下:
   select * from table1 with(updlock) where ....


sqlserver死鎖檢查工具

代碼如下


if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[sp_who_lock]') and

OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[sp_who_lock]
GO


use master
go
create procedure sp_who_lock
as
begin
declare @spid int,@bl int,
@intTransactionCountOnEntry int,
@intRowcount int,
@intCountProperties int,
@intCounter int

create table #tmp_lock_who (
id int identity(1,1),
spid smallint,
bl smallint)

IF @@ERROR<>0 RETURN @@ERROR

insert into #tmp_lock_who(spid,bl) select 0 ,blocked
from (select * from sysprocesses where blocked>0 ) a
where not exists(select * from (select * from sysprocesses where blocked>0 ) b
where a.blocked=spid)
union select spid,blocked from sysprocesses where blocked>0

IF @@ERROR<>0 RETURN @@ERROR

-- 找到臨時表的記錄數(shù)
select @intCountProperties = Count(*),@intCounter = 1
from #tmp_lock_who

IF @@ERROR<>0 RETURN @@ERROR

if @intCountProperties=0
select '現(xiàn)在沒有阻塞和死鎖信息' as message

-- 循環(huán)開始
while @intCounter <= @intCountProperties
begin
-- 取第一條記錄
select @spid = spid,@bl = bl
from #tmp_lock_who where Id = @intCounter
begin
if @spid =0
select '引起數(shù)據(jù)庫死鎖的是: '+ CAST(@bl AS VARCHAR(10)) + '進(jìn)程號,其執(zhí)行的SQL語法如下'
else
select '進(jìn)程號SPID:'+ CAST(@spid AS VARCHAR(10))+ '被' + '進(jìn)程號SPID:'+ CAST(@bl AS VARCHAR

(10)) +'阻塞,其當(dāng)前進(jìn)程執(zhí)行的SQL語法如下'
DBCC INPUTBUFFER (@bl )
end

-- 循環(huán)指針下移
set @intCounter = @intCounter + 1
end


drop table #tmp_lock_who

return 0
end

死鎖處理方法:

(1). 根據(jù)2中提供的sql,查看那個spid處于wait狀態(tài),然后用kill spid來干掉(即破壞死鎖的第四個必要條件:循環(huán)

等待);當(dāng)然這只是一種臨時解決方案,我們總不能在遇到死鎖就在用戶的生產(chǎn)環(huán)境上排查死鎖、Kill sp,我們應(yīng)該

考慮如何去避免死鎖。

(2). 使用SET LOCK_TIMEOUT timeout_period(單位為毫秒)來設(shè)定鎖請求超時。默認(rèn)情況下,數(shù)據(jù)庫沒有超時期限

代碼如下

(timeout_period值為-1,可以用SELECT @@LOCK_TIMEOUT來查看該值,即無限期等待)。當(dāng)請求鎖超過timeout_period

時,將返回錯誤。timeout_period值為0時表示根本不等待,一遇到鎖就返回消息。設(shè)置鎖請求超時,破環(huán)了死鎖的第

二個必要條件(請求與保持條件)。

服務(wù)器: 消息 1222,級別 16,狀態(tài) 50,行 1
已超過了鎖請求超時時段。


(3). SQL Server內(nèi)部有一個鎖監(jiān)視器線程執(zhí)行死鎖檢查,鎖監(jiān)視器對特定線程啟動死鎖搜索時,會標(biāo)識線程正在等待

的資源;然后查找特定資源的所有者,并遞歸地繼續(xù)執(zhí)行對那些線程的死鎖搜索,直到找到一個構(gòu)成死鎖條件的循環(huán)

。檢測到死鎖后,數(shù)據(jù)庫引擎 選擇運行回滾開銷最小的事務(wù)的會話作為死鎖犧牲品,返回1205 錯誤,回滾死鎖犧牲

品的事務(wù)并釋放該事務(wù)持有的所有鎖,使其他線程的事務(wù)可以請求資源并繼續(xù)運行。

死鎖示例及解決方法
5.1 SQL死鎖
(1). 測試用的基礎(chǔ)數(shù)據(jù):

代碼如下

CREATE TABLE Lock1(C1 int default(0));
CREATE TABLE Lock2(C1 int default(0));
INSERT INTO Lock1 VALUES(1);
INSERT INTO Lock2 VALUES(1);


(2). 開兩個查詢窗口,分別執(zhí)行下面兩段sql

代碼如下

--Query 1
Begin Tran
Update Lock1 Set C1=C1+1;
WaitFor Delay '00:01:00';
SELECT * FROM Lock2
Rollback Tran;


--Query 2
Begin Tran
Update Lock2 Set C1=C1+1;
WaitFor Delay '00:01:00';
SELECT * FROM Lock1
Rollback Tran;

上面的SQL中有一句WaitFor Delay '00:01:00',用于等待1分鐘,以方便查看鎖的情況。


解決辦法
a). SQL Server自動選擇一條SQL作死鎖犧牲品:運行完上面的兩個查詢后,我們會發(fā)現(xiàn)有一條SQL能正常執(zhí)行完畢,

而另一個SQL則報如下錯誤:

服務(wù)器: 消息 1205,級別 13,狀態(tài) 50,行 1
事務(wù)(進(jìn)程 ID xx)與另一個進(jìn)程已被死鎖在 lock 資源上,且該事務(wù)已被選作死鎖犧牲品。請重新運行該事務(wù)。
這就是上面第四節(jié)中介紹的鎖監(jiān)視器干活了。

b). 按同一順序訪問對象:顛倒任意一條SQL中的Update與SELECT語句的順序。例如修改第二條SQL成如下:

代碼如下

--Query2
Begin Tran
SELECT * FROM Lock1--在Lock1上申請S鎖
WaitFor Delay '00:01:00';
Update Lock2 Set C1=C1+1;--Lock2:RID:X
Rollback Tran;


當(dāng)然這樣修改也是有代價的,這會導(dǎo)致第一條SQL執(zhí)行完畢之前,第二條SQL一直處于阻塞狀態(tài)。單獨執(zhí)行Query1或

Query2需要約1分鐘,但如果開始執(zhí)行Query1時,馬上同時執(zhí)行Query2,則Query2需要2分鐘才能執(zhí)行完;這種按順序

請求資源從一定程度上降低了并發(fā)性。

c). SELECT語句加With(NoLock)提示:默認(rèn)情況下SELECT語句會對查詢到的資源加S鎖(共享鎖),S鎖與X鎖(排他鎖)不

兼容;但加上With(NoLock)后,SELECT不對查詢到的資源加鎖(或者加Sch-S鎖,Sch-S鎖可以與任何鎖兼容);從而可

以是這兩條SQL可以并發(fā)地訪問同一資源。當(dāng)然,此方法適合解決讀與寫并發(fā)死鎖的情況,但加With(NoLock)可能會導(dǎo)

致臟讀。

代碼如下

SELECT * FROM Lock2 WITH(NOLock)
SELECT * FROM Lock1 WITH(NOLock)

d). 使用較低的隔離級別。SQL Server 2000支持四種事務(wù)處理隔離級別(TIL),分別為:READ UNCOMMITTED、READ

COMMITTED、REPEATABLE READ、SERIALIZABLE;SQL Server 2005中增加了SNAPSHOT TIL。默認(rèn)情況下,SQL Server使

用READ COMMITTED TIL,我們可以在上面的兩條SQL前都加上一句SET TRANSACTION ISOLATION LEVEL READ

UNCOMMITTED,來降低TIL以避免死鎖;事實上,運行在READ UNCOMMITTED TIL的事務(wù),其中的SELECT語句不對結(jié)果資

源加鎖或加Sch-S鎖,而不會加S鎖;但還有一點需要注意的是:READ UNCOMMITTED TIL允許臟讀,雖然加上了降低TIL

的語句后,上面兩條SQL在執(zhí)行過程中不會報錯,但執(zhí)行結(jié)果是一個返回1,一個返回2,即讀到了臟數(shù)據(jù),也許這并不

是我們所期望的。

e). 在SQL前加SET LOCK_TIMEOUT timeout_period,當(dāng)請求鎖超過設(shè)定的timeout_period時間后,就會終止當(dāng)前SQL的

執(zhí)行,犧牲自己,成全別人。

f). 使用基于行版本控制的隔離級別(SQL Server 2005支持):開啟下面的選項后,SELECT不會對請求的資源加S鎖,

不加鎖或者加Sch-S鎖,從而將讀與寫操作之間發(fā)生的死鎖幾率降至最低;而且不會發(fā)生臟讀。啊

SET ALLOW_SNAPSHOT_ISOLATION ON
SET READ_COMMITTED_SNAPSHOT ON

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文檔

SQLServer數(shù)據(jù)庫死鎖原因與解決辦法

SQLServer數(shù)據(jù)庫死鎖原因與解決辦法:SQL Server數(shù)據(jù)庫死鎖,通俗的講就是兩個或多個trans,同時請求對方正在請求的某個實際應(yīng)用對象,而導(dǎo)致雙方互相等待。簡單的例子如下: sql server死鎖表現(xiàn)一: 一個用戶A 訪問表A(鎖住了表A),然后又訪問表B 另一個用戶B 訪問表B(鎖住了表B),然后企
推薦度:
  • 熱門焦點

最新推薦

猜你喜歡

熱門推薦

專題
Top
主站蜘蛛池模板: 99视频都是精品热在线播放 | 久久亚洲伊人中字综合精品 | 国产福利一区二区三区 | 日本三级免费 | 欧美色图亚洲激情 | 欧美亚洲另类视频 | 成人久久精品 | 国产免费一区二区三区 | 人人添人人澡人人澡人人人爽 | 亚洲区中文字幕 | 国产特级全黄一级毛片不卡 | 国内精品视频在线播放 | 国产日韩欧美精品在线 | 日韩欧美中字 | 99精品国产免费久久国语 | 日韩欧美中字 | 免费一级a毛片在线播放视 免费一区二区 | 国产 欧美 日本 | 亚洲 欧美 日韩 在线 | 91视频高清 | 中国一级全黄的免费观看 | 亚洲一区日韩二区欧美三区 | 亚洲情a成黄在线观看动 | 国产成人精品一区二区免费视频 | 国产一级视频 | 久久艹精品 | 日韩欧美一区二区三区中文精品 | 亚洲欧美天堂网 | 91精品一区二区三区久久久久 | 欧美亚洲国产精品久久久 | 日韩影片在线观看 | 国产成人久久精品一区二区三区 | 国产一区二区三区在线视频 | 亚洲欧美在线看 | 亚洲三级电影网 | 性色a v 一区 | 精品日本一区二区三区在线观看 | 国产精品观看 | 亚洲黄色一区 | 国产精品美女久久久久 | 欧美一区二区三区在线播放 |