1. 程式人生 > 實用技巧 >鎖-學習筆記(三)

鎖-學習筆記(三)

常見資源附加的鎖

資料庫鎖

資料庫鎖有共享、更新、排他3種模式。雖然這3種鎖會影響使用者對資料庫中表資料的操作,但這3種鎖的產生原因與表的邏輯資料操作都沒有關係,與事務也沒關係。

共享鎖:資料庫的所有連線會自動對資料庫附加共享鎖,以防止在操作過程中刪除資料庫或離線資料庫(offline)。

更新鎖:對某些操作,如執行alter database操作使得資料庫離線或修改資料庫的設定時,為了降低產生死鎖的機會,會先對資料庫附加更新鎖,然後再把更新鎖轉換為排他鎖,轉換成功後才能完成alter database操作。alter database語句不能放置於顯示事務中執行,必須作為一個事務單獨執行,從而對資料庫附加排他鎖及更新鎖的時間一般不會持續過長,對資料庫中其他操作的影響一般也很小。

排他鎖:當某個資料庫操作需要排他使用時,如刪除資料庫或修改資料庫名稱時,會對資料庫直接附加X鎖。

因為master和tempdb資料庫不能離線,也不能被刪除,所以這兩個資料庫一般不會加鎖。

建立一個數據名稱為testLock,並在該資料庫中建立鎖-學習筆記(二)中的鎖查詢檢視dbLocks,對testLock資料庫啟動兩個連線(新建兩個查詢),假設為連線1、連線2。

在連線1中查詢當前鎖的資訊,可以看到這兩個連線對資料各自附加了一個共享鎖,各個列的含義詳見鎖-學習筆記(二)

select * from dbLocks
go

在連線2中執行資料庫離線命令

alter database
testLock set offline go

重新在連線1查詢鎖的情況

select * from dbLocks
go

由查詢結果的第1行和第4行可以發現,因為更新鎖與共享鎖相容,當連線2執行資料庫離線操作時,對資料庫附加了更新鎖,而在更新鎖轉換為排他鎖時,則與連線1附加的共享鎖互斥而發生等待。

取消連線2中的操作,然後在連線2中執行下面的命令修改資料庫名稱:

use master
go
alter database testLock modify name=testLock1
go

連線2中的當前修改資料庫名稱操作會發生等待。

在連線1中,查詢當前鎖的情況,可以發現,修改資料庫名稱直接對其附加了排他鎖:

select * from dbLocks
go

如果等待時間過長,連線2中的操作會被取消,並給出以下錯誤資訊:

在連線2中執行刪除資料庫也會發生等待:

use master
go
drop database testLock 
go

在連線1中查詢鎖的情況,會發現執行刪除資料庫操作時,對其附加了排他鎖:

一段時間後連線2會給出以下錯誤資訊:

對資料庫新增檔案組或資料檔案、修改資料檔案大小都不會對資料庫附加排他鎖,刪除檔案組或資料檔案只取決於檔案組或資料檔案中是否已經存放了資料,也不會對資料庫附加排他鎖。

alter database testLock add filegroup testPFS
go
alter database testLock
add file
(
   name='testPFS_data',
   filename='e:\sqldata\testPFS_data.ndftestLock.ndf'
)
to filegroup testPFS
go