這篇博文簡單介紹一下在sql server中一條insert語句中用到的鎖。
首先我們建立一張表table_1,它有兩列id(bigint)和value(varchar),其中id建立了主鍵。
createview codetable
[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
]
然後插入兩條資料。
insert我們知道,在transaction中共享鎖在查詢語句結束就釋放了,而排它鎖則在transaction提交才釋放。我們可以利用它來執行乙個insert,不提交transaction,然後去檢視鎖的狀態。注意,本文中查詢視窗配置的transaction隔離級別是預設值read committed。into
dbo.table_2
(id, value)
values
(1, '1'
),(2, '
2');
首先執行以下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來看看第一條sql產生的鎖。由於共享鎖會在查詢結束立即釋放,因此我們加乙個holdlock,讓它在事務結束再釋放:*from
dbo.table_2
where id=
3;
begin這是執行完以上語句鎖的情況:tran
t2select
*from dbo.table_2 with(holdlock
)where id=
1;
第二條sql會產生阻塞,因此可以直接查詢然後看鎖的情況:
我們發現第9行的resource_description和第3行是相同的,這也說明了主鍵的鎖只是鎖住了某乙個值而已。
這條sql也會被insert阻塞:
select而且檢視當前的鎖可以發現,key被鎖的值正是insert語句的key值。這裡有兩個疑問:1. 為什麼沒用到主鍵列,卻產生了主鍵鎖。2.為什麼insert的資料還未commit,這裡卻會產生這一行主鍵的鎖。value
from
dbo.table_2
where
value='
1'
答: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 值。乙個作用域就是乙個模組 儲存過程 ...