今天有被問到:sqlserver鎖定一行的最小鎖是什嗎?
當時答曰:行級鎖
回來查文檔,得有關鎖的資訊(sql2k用syslockinfo表查, sql2k5用sys.dm_tran_locks表查):
資源類型:
1 = NULL 資源(未使用)
2 = 資料庫
3 = 檔案
4 = 索引
5 = 表
6 = 頁
7 = 鍵
8 = 區
9 = RID(行 ID)
10 = 應用程式
OK,現在來看看鎖定到一行的最小層級的鎖是什麼。
1D:\Program Files\Microsoft SQL Server\90\Tools\Binn>osql -Usa -Pdba123 -Sdragon
21> create table t_pk(t_id int primary key, t_desc varchar(50));
32> create table t_heap(t_id int, t_desc varchar(50));
43> go
51> insert into t_pk values(1, 'welcome');
62> insert into t_pk values(2, 'nice to meet you');
73> insert into t_pk values(3, 'wall street, stock');
84> go
9(1 行受影響)
10(1 行受影響)
11(1 行受影響)
121> insert into t_heap select * from t_pk;
132> go
14(3 行受影響)
151> begin tran
162> update t_pk set t_desc = 'have a nice day' where t_id = 3;
173> go
18(1 行受影響)
19
現在,我更新有主鍵的表t_pk,看看sqlserver鎖了些什麼東東:
這裡,sqlserver對t_pk表以及相應的page加上了IX鎖,對更新的那一行加上了X鎖。
再來,現在試試對堆表的更新:
1> rollback;
2> go
1> begin tran
2> update t_heap set t_desc = 'have a nice day' where t_id = 3;
3> go
看看sqlserver對堆表鎖了些什麼:
sqlserver 2005很聰明,也只鎖了一行(曾記得,sql2k對堆表會鎖住一個page的,待找sql2k再測試)。
這2個測試中的鎖定,一個是KEY, 一個是RID, 基本符合我所說的行級鎖的意思。但真較上勁的話,我的答案又似乎不足,:)