SQL Server中如何減少死鎖,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
創(chuàng)新互聯(lián)主要從事網(wǎng)站設(shè)計、做網(wǎng)站、網(wǎng)頁設(shè)計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)波密,十余年網(wǎng)站建設(shè)經(jīng)驗,價格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):028-86922220
減少SQLServer死鎖的方法有哪些
如事務(wù)1的線程T1具有表A上的排它鎖,事務(wù)2的線程T2具有表B上的排它鎖,并且之后需要表A上的鎖。事務(wù)2無法獲得這一鎖,因為事務(wù)1已擁有它。事務(wù)2被阻塞,等待事務(wù)1。然后,事務(wù)1需要表B的鎖,但無法獲得鎖,因為事務(wù)2將它鎖定了。事務(wù)在提交或回滾之前不能釋放持有的鎖。因為事務(wù)需要對方控制的鎖才能繼續(xù)操作,所以它們不能提交或回滾,這樣數(shù)據(jù)庫就會發(fā)生死鎖了。
如在編寫存儲過程的時候,由于有些存儲過程事務(wù)性的操作比較頻繁,假如先鎖住表A,再鎖住表B,那么在所有的存儲過程中都要按照這個順序來鎖定它們。假如無意中某個存儲過程中先鎖定表B,再鎖定表A,這可能就會導(dǎo)致一個死鎖。而且死鎖一般是不太容易被發(fā)現(xiàn)的。
假如服務(wù)器上經(jīng)常出現(xiàn)這種死鎖情況,就會降低服務(wù)器的性能,所以應(yīng)用程序在使用的時候,我們就需要對其進(jìn)行跟蹤,使用sp_who和sp_who2來確定可能是哪些用戶阻塞了其他用戶,我們還可以用下面的存儲過程來跟蹤具體的死鎖執(zhí)行的影響:
createproceduresp_who_lock
as
begin
declare@spidint,@blint,
@intTransactionCountOnEntryint,
@intRowcountint,
@intCountPropertiesint,
@intCounterint
createtable#tmp_lock_who(idintidentity(1,1),spidsmallint,blsmallint)
IF@@ERROR<>0RETURN@@ERROR
insertinto#tmp_lock_who(spid,bl)select0,blocked
from(select*fromsysprocesseswhereblocked>0)a
wherenotexists(select*from(select*fromsysprocesseswhereblocked>0)b
wherea.blocked=spid)
unionselectspid,blockedfromsysprocesseswhereblocked>0
IF@@ERROR<>0RETURN@@ERROR
--找到臨時表的記錄數(shù)
select@intCountProperties=Count(*),@intCounter=1
from#tmp_lock_who
IF@@ERROR<>0RETURN@@ERROR
if@intCountProperties=0
select’現(xiàn)在沒有阻塞和死鎖信息’asmessage
--循環(huán)開始
while@intCounter<=@intCountProperties begin --取第一條記錄 select@spid=spid,@bl=bl from#tmp_lock_whowhereid=@intCounter begin if@spid=0 select’引起數(shù)據(jù)庫死鎖的是:’+CAST(@blASVARCHAR(10))+’進(jìn)程號,其執(zhí)行的SQL語法如下’ else select’進(jìn)程號SPID:’+CAST(@spidASVARCHAR(10))+’被’+’進(jìn)程號SPID:’+CAST(@blASVARCHAR(10))+’阻塞,其當(dāng)前進(jìn)程執(zhí)行的SQL語法如下’ DBCCINPUTBUFFER(@bl) end --循環(huán)指針下移 set@intCounter=@intCounter+1 end droptable#tmp_lock_who return0 end 減少SQLServer死鎖的方法有哪些 我們只需要通過在查詢分析器里面執(zhí)行sp_who_lock,就可以具體捕捉到執(zhí)行的堵塞進(jìn)程,這時我們就可以對對應(yīng)的SQL語句或者存儲過程進(jìn)行性能上面的改進(jìn)及設(shè)計。[Page] 所以我們在數(shù)據(jù)庫設(shè)計的時候,雖然不能完全避免死鎖,但可以使死鎖的數(shù)量盡量減少。增加事務(wù)的吞吐量并減少系統(tǒng)開銷,因為只有很少的事務(wù),所以就得遵循下面的原則: 按同一順序訪問對象 假如所有并發(fā)事務(wù)按同一順序訪問對象,則發(fā)生死鎖的可能性會降低。在寫SQL語句或存儲過程的時候,就需要按照順序在兩個并發(fā)事務(wù)中先獲得表A上的鎖,然后獲得表B上的鎖,當(dāng)?shù)谝粋€事務(wù)完成之前,另一個事務(wù)被阻塞在表A上。第一個事務(wù)提交或回滾后,第二個事務(wù)繼續(xù)進(jìn)行,而不能在語句里面寫先獲得表B上的鎖,然后再獲得表A的鎖。 避免事務(wù)中的用戶交互 避免編寫包含用戶交互的事務(wù),因為運(yùn)行沒有用戶交互的批處理的速度要遠(yuǎn)遠(yuǎn)快于用戶手動響應(yīng)查詢的速度,例如答復(fù)應(yīng)用程序請求參數(shù)的提示。例如,假如事務(wù)正在等待用戶輸入,而用戶就去做別的事了,則用戶將此事務(wù)掛起使之不能完成。這樣將降低系統(tǒng)的吞吐量,因為事務(wù)持有的任何鎖只有在事務(wù)提交或回滾時才會釋放。即使不出現(xiàn)死鎖的情況,訪問同一資源的其它事務(wù)也會被阻塞,等待該事務(wù)完成。 保持事務(wù)簡短并在一個批處理中 在同一數(shù)據(jù)庫中并發(fā)執(zhí)行多個需要長時間運(yùn)行的事務(wù)時通常發(fā)生死鎖。事務(wù)運(yùn)行時間越長,其持有排它鎖或更新鎖的時間也就越長,從而堵塞了其它活動并可能導(dǎo)致死鎖。保持事務(wù)在一個批處理中,可以最小化事務(wù)的網(wǎng)絡(luò)通信往返量,減少完成事務(wù)可能的延遲并釋放鎖。 使用低隔離級別 確定事務(wù)是否能在更低的隔離級別上運(yùn)行。執(zhí)行提交讀允許事務(wù)讀取另一個事務(wù)已讀取(未修改)的數(shù)據(jù),而不必等待第一個事務(wù)完成。使用較低的隔離級別(例如提交讀)而不使用較高的隔離級別(例如可串行讀)可以縮短持有共享鎖的時間,從而降低了鎖定爭奪。 使用綁定連接 使用綁定連接使同一應(yīng)用程序所打開的兩個或多個連接可以相互合作。次級連接所獲得的任何鎖可以象由主連接獲得的鎖那樣持有,反之亦然,因此不會相互阻塞。
下面有一些對死鎖發(fā)生的一些建議:
1)對于頻繁使用的表使用集簇化的索引;
2)設(shè)法避免一次性影響大量記錄的T-SQL語句,特別是INSERT和UPDATE語句;
3)設(shè)法讓UPDATE和DELETE語句使用索引;
4)使用嵌套事務(wù)時,避免提交和回退沖突;
5)對一些數(shù)據(jù)不需要及時讀取更新值的表在寫SQL的時候在表后臺加上(nolock),如:Select*fromtableA(nolock)。
看完上述內(nèi)容,你們掌握SQL Server中如何減少死鎖的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!
當(dāng)前題目:SQLServer中如何減少死鎖
文章鏈接:http://muchs.cn/article4/gjscie.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、定制網(wǎng)站、Google、虛擬主機(jī)、建站公司、定制開發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)