沒法得到數據庫'model'上的排他鎖 解決辦法

 

今天在編寫建庫工具的時候遇到排他鎖問題,數據庫創建失敗,從百度中看到了,想與你們分享.html

解決方法:sql

在查詢分析器中運行以下代碼便可:數據庫

declare @sql varchar(100)
while 1=1
begin
select top 1 @sql = 'kill '+cast(spid as varchar(3))
from master..sysprocesses
where spid > 50 and spid <> @@spid
if @@rowcount = 0
break
exec(@sql)
end
服務器

死鎖是指在某組資源中,兩個或兩個以上的線程在執行過程當中,在爭奪某一資源時而形成互相等待的現象,若無外力的做用下,它們都將沒法推動下去,死時就可能會產生死鎖,這些永遠在互相等待的進程稱爲死鎖線程。簡單的說,進程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來肯定多是哪些用戶阻塞了其餘用戶,咱們還能夠用下面的存儲過程來跟蹤具體的死鎖執行的影響工具

咱們只須要經過在查詢分析器裏面執行sp_who_lock,就能夠具體捕捉到執行的堵塞進程,這時咱們就能夠對對應的SQL語句或者存儲過程進行性能上面的改進及設計。性能

因此咱們在數據庫設計的時候,雖然不能徹底避免死鎖,但可使死鎖的數量儘可能減小。增長事務的吞吐量並減小系統開銷,由於只有不多的事務,因此就得遵循下面的原則:線程

按同一順序訪問對象

若是全部併發事務按同一順序訪問對象,則發生死鎖的可能性會下降。在寫SQL語句或存儲過程的時候,就須要按照順序在兩個併發事務中先得到表A上的鎖,而後得到表B上的鎖,當第一個事務完成以前,另外一個事務被阻塞在表A上。第一個事務提交或回滾後,第二個事務繼續進行,而不能在語句裏面寫先得到表B上的鎖,而後再得到表A的鎖。

避免事務中的用戶交互

避免編寫包含用戶交互的事務,由於運行沒有用戶交互的批處理的速度要遠遠快於用戶手動響應查詢的速度,例如答覆應用程序請求參數的提示。例如,若是事務正在等待用戶輸入,而用戶就去作別的事了,則用戶將此事務掛起使之不能完成。這樣將下降系統的吞吐量,由於事務持有的任何鎖只有在事務提交或回滾時纔會釋放。即便不出現死鎖的狀況,訪問同一資源的其它事務也會被阻塞,等待該事務完成。

保持事務簡短並在一個批處理中

在同一數據庫中併發執行多個須要長時間運行的事務時一般發生死鎖。事務運行時間越長,其持有排它鎖或更新鎖的時間也就越長,從而堵塞了其它活動並可能致使死鎖。保持事務在一個批處理中,能夠最小化事務的網絡通訊往返量,減小完成事務可能的延遲並釋放鎖。

使用低隔離級別

肯定事務是否能在更低的隔離級別上運行。執行提交讀容許事務讀取另外一個事務已讀取(未修改)的數據,而沒必要等待第一個事務完成。使用較低的隔離級別(例如提交讀)而不使用較高的隔離級別(例如可串行讀)能夠縮短持有共享鎖的時間,從而下降了鎖定爭奪。

使用綁定鏈接

使用綁定鏈接使同一應用程序所打開的兩個或多個鏈接能夠相互合做。次級鏈接所得到的任何鎖能夠象由主鏈接得到的鎖那樣持有,反之亦然,所以不會相互阻塞。

下面有一些對死鎖發生的一些建議:

(1)對於頻繁使用的表使用集簇化的索引;

(2)設法避免一次性影響大量記錄的T-SQL語句,特別是INSERT和UPDATE語句;

(3)設法讓UPDATE和DELETE語句使用索引;

(4)使用嵌套事務時,避免提交和回退衝突;

(5)對一些數據不須要及時讀取更新值的表在寫SQL的時候在表後臺加上(nolock),如:Select * from tableA(nolock)

相關文章
相關標籤/搜索