SQL Server Insert操作中的鎖

2022-02-12 11:22:49 字數 2571 閱讀 1241

這篇博文簡單介紹一下在sql server中一條insert語句中用到的鎖。

首先我們建立一張表table_1,它有兩列id(bigint)和value(varchar),其中id建立了主鍵。

create

table

[dbo

].[table_2](

[id][

bigint

]not

null

,

[value][

nchar

](10) null,

constraint

[pk_table_2

]primary

keyclustered

( [id

]asc

)with (pad_index =

off, statistics_norecompute =

off, ignore_dup_key =

off, allow_row_locks =

on, allow_page_locks =

on) on

[primary])

on[primary

]

view code

然後插入兩條資料。

insert

into

dbo.table_2

(id, value)

values

(1, '1'

),(2, '

2');

我們知道,在transaction中共享鎖在查詢語句結束就釋放了,而排它鎖則在transaction提交才釋放。我們可以利用它來執行乙個insert,不提交transaction,然後去檢視鎖的狀態。注意,本文中查詢視窗配置的transaction隔離級別是預設值read committed。

首先執行以下sql:

begin

tran

t1insert

into

dbo.table_2

(id, value)

values

(3, '

3');

然後檢視鎖:

select

resource_type,

request_mode,

resource_description,

request_session_id,

request_status,

resource_associated_entity_id,

db_name(resource_database_id)as

resource_database

from

sys.dm_tran_locks

where

resource_type

<>

'database

'order

byrequest_session_id;

執行結果如下:

此時,我們在另外乙個命令視窗中執行以下查詢語句不會產生阻塞:

select

*from

dbo.table_2

where id=

1;

但另一條卻會產生阻塞:

select

*from

dbo.table_2

where id=

3;

來看看第一條sql產生的鎖。由於共享鎖會在查詢結束立即釋放,因此我們加乙個holdlock,讓它在事務結束再釋放:

begin

tran

t2select

*from dbo.table_2 with(holdlock

)where id=

1;

這是執行完以上語句鎖的情況:

第二條sql會產生阻塞,因此可以直接查詢然後看鎖的情況:

我們發現第9行的resource_description和第3行是相同的,這也說明了主鍵的鎖只是鎖住了某乙個值而已。

這條sql也會被insert阻塞:

select

value

from

dbo.table_2

where

value='

1'

而且檢視當前的鎖可以發現,key被鎖的值正是insert語句的key值。這裡有兩個疑問:1. 為什麼沒用到主鍵列,卻產生了主鍵鎖。2.為什麼insert的資料還未commit,這裡卻會產生這一行主鍵的鎖。

答:1. 我們檢視查詢計畫,可以看到這條語句是用了聚集索引掃瞄,至於為什麼不是表掃瞄,請看這裡。 2. 由於事務隔離級別預設是read committed,所以這裡會對已插入但未提交的資料主鍵加乙個共享鎖。

SQL Server Insert操作中的鎖

這篇博文簡單介紹一下在sql server中一條insert語句中用到的鎖。首先我們建立一張表table 1,它有兩列id bigint 和value varchar 其中id建立了主鍵。view code 然後插入兩條資料。insert into dbo.table 2 id,value valu...

SQL Server Insert操作中的鎖

這篇博文簡單介紹一下在sql server中一條insert語句中用到的鎖。首先我們建立一張表table 1,它有兩列id bigint 和value varchar 其中id建立了主鍵。view code 然後插入兩條資料。insert into dbo.table 2 id,value valu...

sqlserver insert 後的主鍵獲取方式

sql server 中,可以使用 scope identity identity ident current 來取得最後插入記錄的值值,它們的區別在於 scope identity 返回插入到同一作用域中的 identity 列內的最後乙個 identity 值。乙個作用域就是乙個模組 儲存過程 ...