減少SQL Server死鎖的方法
鎖是指在某組資源中,兩個或兩個以上的執行緒在執行過程中,在爭奪某一資源時而造成互相等待的現象,若無外力的作用下,它們都將無法推進下去,死時就可能會產生死鎖,這些永遠在互相等待的程式稱為死鎖執行緒。簡單的說,程式A等待程式B釋放他的資源,B又等待A釋放他的資源,這樣互相等待就形成死鎖。
如在資料庫中,如果需要對一條資料進行修改,首先資料庫管理系統會在上面加鎖,以保證在同一時間只有一個事務能進行修改操作。如事務1的執行緒 T1具有表A上的排它鎖,事務2的執行緒T2 具有表B上的排它鎖,並且之後需要表A上的鎖。事務2無法獲得這一鎖,因為事務1已擁有它。事務2被阻塞,等待事務1。然後,事務1需要表B的鎖,但無法獲得鎖,因為事務2將它鎖定了。事務在提交或回滾之前不能釋放持有的鎖。因為事務需要對方控制的鎖才能繼續操作,所以它們不能提交或回滾,這樣資料庫就會發生死鎖了。
如在編寫儲存過程的時候,由於有些儲存過程事務性的操作比較頻繁,如果先鎖住表A,再鎖住表B,那麼在所有的儲存過程中都要按照這個順序來鎖定它們。如果無意中某個儲存過程中先鎖定表B,再鎖定表A,這可能就會導致一個死鎖。而且死鎖一般是不太容易被發現的。
如果伺服器上經常出現這種死鎖情況,就會降低伺服器的效能,所以應用程式在使用的時候,我們就需要對其進行跟蹤,使用sp_who和sp_who2來確定可能是哪些使用者阻塞了其他使用者,我們還可以用下面的儲存過程來跟蹤具體的死鎖執行的影響:
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
-- 找到臨時表的記錄數
select @intCountProperties = Count(*),@intCounter = 1
from #tmp_lock_who
IF @@ERROR<>0 RETURN @@ERROR
if @intCountProperties=0
select ’現在沒有阻塞和死鎖資訊’ as message
-- 迴圈開始
while @intCounter <= @intCountProperties
begin
-- 取第一條記錄
select @spid = spid,@bl = bl
from #tmp_lock_who where id = @intCounter
begin
if @spid =0
select ’引起資料庫死鎖的是: ’+ CAST(@bl AS VARCHAR(10)) + ’程式號,其執行的SQL語法如下’
else
select ’程式號SPID:’+ CAST(@spid AS VARCHAR(10))+ ’被’ + ’程式號SPID:’+ CAST(@bl AS VARCHAR(10)) +’阻塞,其當前程式執行的SQL語法如下’
DBCC INPUTBUFFER (@bl )
end
-- 迴圈指標下移
set @intCounter = @intCounter + 1
end
drop table #tmp_lock_who
return 0
end
我們只需要透過在查詢分析器裡面執行sp_who_lock,就可以具體捕捉到執行的堵塞程式,這時我們就可以對對應的SQL語句或者儲存過程進行效能上面的改進及設計。 [Page]
所以我們在資料庫設計的時候,雖然不能完全避免死鎖,但可以使死鎖的數量儘量減少。增加事務的吞吐量並減少系統開銷,因為只有很少的事務,所以就得遵循下面的原則:
按同一順序訪問物件
如果所有併發事務按同一順序訪問物件,則發生死鎖的可能性會降低。在寫SQL語句或儲存過程的時候,就需要按照順序在兩個併發事務中先獲得表A上的鎖,然後獲得表B上的鎖,當第一個事務完成之前,另一個事務被阻塞在表A上。第一個事務提交或回滾後,第二個事務繼續進行,而不能在語句裡面寫先獲得表B上的鎖,然後再獲得表A的鎖。
避免事務中的使用者互動
避免編寫包含使用者互動的事務,因為執行沒有使用者互動的批處理的速度要遠遠快於使用者手動響應查詢的速度,例如答覆應用程式請求引數的提示。例如,如果事務正在等待使用者輸入,而使用者就去做別的事了,則使用者將此事務掛起使之不能完成。這樣將降低系統的吞吐量,因為事務持有的任何鎖只有在事務提交或回滾時才會釋放。即使不出現死鎖的情況,訪問同一資源的其它事務也會被阻塞,等待該事務完成。
保持事務簡短並在一個批處理中
在同一資料庫中併發執行多個需要長時間執行的事務時通常發生死鎖。事務執行時間越長,其持有排它鎖或更新鎖的時間也就越長,從而堵塞了其它活動並可能導致死鎖。保持事務在一個批處理中,可以最小化事務的網路通訊往返量,減少完成事務可能的延遲並釋放鎖。
使用低隔離級別
確定事務是否能在更低的隔離級別上執行。執行提交讀允許事務讀取另一個事務已讀取(未修改)的資料,而不必等待第一個事務完成。使用較低的隔離級別(例如提交讀)而不使用較高的隔離級別(例如可序列讀)可以縮短持有共享鎖的時間,從而降低了鎖定爭奪。
使用繫結連線
使用繫結連線使同一應用程式所開啟的兩個或多個連線可以相互合作。次級連線所獲得的任何鎖可以象由主連線獲得的鎖那樣持有,反之亦然,因此不會相互阻塞。
下面有一些對死鎖發生的一些建議:
1)對於頻繁使用的表使用集簇化的索引;
2)設法避免一次性影響大量記錄的T-SQL語句,特別是INSERT和UPDATE語句;
3)設法讓UPDATE和DELETE語句使用索引;
4)使用巢狀事務時,避擴音交和回退衝突;
5)對一些資料不需要及時讀取更新值的表在寫SQL的時候在表後臺加上(nolock),如:Select * from tableA(nolock) 。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/66009/viewspace-1029648/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SQL Server 的死鎖SQLServer
- SQL Server死鎖SQLServer
- sql server死鎖的問題SQLServer
- [zt] sql server 死鎖總結SQLServer
- 減少該死的 if else 巢狀巢狀
- [zt] Sql Server死鎖的查詢和解除SQLServer
- 減少SQL日誌的三種方法(轉)SQL
- 減少程式碼中該死的 if else 巢狀巢狀
- 有關於SQL Server資料庫死鎖的分析(轉)SQLServer資料庫
- 在 SQL Server 中查詢活動連線和死鎖SQLServer
- 如何捕獲和記錄SQL Server中發生的死鎖SQLServer
- SQL Server 資料庫查詢死鎖的處理步驟SQLServer資料庫
- 高效的SQL( clustering factor減少COST)SQL
- SQL Server 鎖SQLServer
- ----------------SQL Server2000中死鎖經驗總結 ---------------SQLServer
- SQL Server 2005 聯機叢書(2007 年 9 月)將死鎖減至最少SQLServer
- 13_共享SQL減少硬解析SQL
- SQL Server 2000 死鎖(dead lock) 問題解決SQLServer
- 使用 TRY/CATCH 語句解決 SQL Server 2005 死鎖SQLServer
- 前端頁面優化,減少 reflow 的方法前端優化
- IIS減少工作執行緒阻塞的方法執行緒
- 解決Oracle死鎖的快捷方法Oracle
- ORACLE中殺死鎖程式的方法Oracle
- oracle 死鎖表解決方法Oracle
- 減小SQL SERVER的日誌檔案SQLServer
- SQL Server 2005遊標的行為變化導致的死鎖問題SQLServer
- SQ死鎖及死鎖的解決
- 程式中減少使用 if 語句的方法集錦
- 程式中減少使用if語句的方法集錦
- [翻譯]:SQL死鎖-阻塞探測SQL
- oracle死鎖的檢視及kill方法Oracle
- SQL Server中的事務與鎖SQLServer
- SQL Server 中的鎖定介紹SQLServer
- SQL SERVER 查詢鎖資訊SQLServer
- 減少C++程式碼編譯時間的方法C++編譯
- 作業系統(5) 死鎖的概念 死鎖產生的必要條件 死鎖的處理策略 預防死鎖 避免死鎖 死鎖的檢測和解除 銀行家演算法作業系統演算法
- Oracle資料表死鎖的解決方法Oracle
- 關於Oracle死鎖處理方法Oracle