Insert語句的鎖


之前一直以為Insert不會對表產生鎖,而事實並非如此吧,下面給出一些實例和證明。

CREATE TABLE [dbo].[TEST1](
    [C1] [varchar](100) NULL,
    [C2] [varchar](100) NULL,
    [C3] [varchar](100) NULL
)

set nocount on
declare @a int=1
begin tran
while @a<=100000
begin
    insert into TEST1
    select newid(),newid(),newid()
    set @a=@a+1
end

 

在會話1窗口中執行如下指令:

BEGIN TRAN
insert into TEST1
select '1','2','3'

 

在會話2窗口中執行如下指令:

SELECT  * FROM TEST1  where C1 ='D638C'

 

你會發現會話2的指令一直在等待,查看具體的鎖情況

SELECT request_owner_id , 
    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' AND DB_NAME(resource_database_id)='CustomDB'
ORDER BY request_owner_id;

 

注: request_owner_id :你開了2個窗口,request_owner_id 就有2個

如上圖,1:表示這個insert語句在某一行上面加了,2:查詢語句在等待會話1提交,結論:在沒有主鍵的表里面,insert語句會導致鎖住整個表,整個表都不能查詢。

下面討論有主鍵的情況:

CREATE TABLE [dbo].[TEST2](
    [C1] [varchar](100)not NULL,
    [C2] [varchar](100) NULL,
    [C3] [varchar](100) NULL
)

set nocount on
declare @a int=1
begin tran
while @a<=100000
begin
    insert into [TEST2]
    select @a,newid(),newid()
    set @a=@a+1
end

alter table [TEST2] add constraint TTT primary key(C1 )

 

會話1:

BEGIN TRAN
insert into [TEST2]
select '00101','2','3'
--        COMMIT TRAN

 

會話2:

SELECT  * FROM TEST2  where C1 ='00101'

 

會話3:

SELECT  * FROM TEST2  where C1 ='1'

 

 

會話4:

SELECT  * FROM TEST2  where C2 ='6900B68A-F4ED-4B44-875A-365C80F8D28A'

 

你會發現會話2、4被阻塞了,但是會話3能夠執行,結論:在有主鍵的表里,並且你用主鍵查詢的時候,insert只會鎖住主鍵值。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM