码迷,mamicode.com
首页 > 数据库 > 详细

SQLServer2012 锁机制测试解析

时间:2016-07-15 20:33:11      阅读:248      评论:0      收藏:0      [点我收藏+]

标签:

SQLServer2012在查询分析器里面开两个连接

插入锁:
结论:“表锁”锁定对该表的Select、Update、Delete操作,但不影响对该表的Insert操作也不影响以主键Id为条件的Select,所以Select如果不想等待就要在Select后加With(Nolock),但这样会产生脏数据就是其他事务已更新但并没有提交的数据,如果该事务进行了RollBack则取出的数据就是错误的,所以好自己权衡利弊,一般情况下90%以上的Select都允许脏读,只有账户金额相关的不允许。
------------------A连接 Insert Lock-------------------
BEGIN TRAN
INSERT INTO dbo.UserInfo
        ( Name, Age, Mobile, AddTime, Type )
VALUES  ( eee, -- Name - varchar(50)
          2, -- Age - int
          555, -- Mobile - char(11)
          GETDATE(), -- AddTime - datetime
          0  -- Type - int
          )
          
SELECT resource_type, request_mode,COUNT(*)  FROM sys.dm_tran_locks
WHERE request_session_id=@@SPID
GROUP BY resource_type,request_mode

--ROLLBACK TRAN

------------------------B连接 Insert Lock------------------------
INSERT INTO dbo.UserInfo
        ( Name, Age, Mobile, AddTime, Type )
VALUES  ( fff, -- Name - varchar(50)
          2, -- Age - int
          123, -- Mobile - char(11)
          GETDATE(), -- AddTime - datetime
          1  -- Type - int
          ) --可以执行插入
          
SELECT * FROM dbo.UserInfo --需要等待解锁
SELECT * FROM dbo.UserInfo WHERE Age=1 --需要等待解锁
SELECT * FROM dbo.UserInfo WHERE Id=3 --可以执行查询(根据主键可以)
SELECT * FROM dbo.UserInfo WITH(NOLOCK) --可以执行查询(在一个事务中,有更新字段但还没有提交,此时就会查处脏数据)
SELECT * FROM dbo.UserInfo WITH(NOLOCK) WHERE Age=1 --可以执行查询
UPDATE dbo.UserInfo SET Type=5 WHERE Name=fff  --需要等待解锁
DELETE FROM dbo.UserInfo WHERE Name=fff --需要等待解锁

更新锁:
结论:“表锁”锁定对该表的Select、Update、Delete操作,但不影响对该表的Insert操作也不影响以主键Id为条件的Select,
-----------------------A连接 Update Lock-----------------------
BEGIN TRAN
UPDATE dbo.UserInfo SET Name = eee WHERE Age = 2

SELECT resource_type, request_mode,COUNT(*)  FROM sys.dm_tran_locks
WHERE request_session_id=@@SPID
GROUP BY resource_type,request_mode

--ROLLBACK TRAN

------------------------B连接 Update Lock------------------------
INSERT INTO dbo.UserInfo
        ( Name, Age, Mobile, AddTime, Type )
VALUES  ( ppp, -- Name - varchar(50)
          15, -- Age - int
          666, -- Mobile - char(11)
          GETDATE(), -- AddTime - datetime
          9  -- Type - int
          ) --可以执行插入
SELECT * FROM dbo.UserInfo --需要等待解锁
SELECT * FROM dbo.UserInfo WHERE Name=ppp --需要等待解锁
SELECT * FROM dbo.UserInfo WHERE Id=3 --可以执行查询(根据主键可以)
SELECT * FROM dbo.UserInfo WITH(NOLOCK) --可以执行查询(在一个事务中,有更新字段但还没有提交,此时就会查处脏数据)
SELECT * FROM dbo.UserInfo WITH(NOLOCK) WHERE Name = ppp --可以执行查询
UPDATE dbo.UserInfo SET Age=8 WHERE Name=ccc --需要等待解锁
DELETE dbo.UserInfo WHERE Age = 5 --需要等待解锁

主键锁:
结论:“行锁+表锁” 锁定对该表的Select、Update、Delete操作,但不影响对该表的Insert操作也不影响以主键Id为条件的Select,

------------------------A连接 Key Lock--------------------
BEGIN TRAN
UPDATE dbo.UserInfo SET Name=hhh WHERE Id=3 --以主键为条件

SELECT resource_type, request_mode,COUNT(*)  FROM sys.dm_tran_locks
WHERE request_session_id=@@SPID
GROUP BY resource_type,request_mode

--ROLLBACK TRAN

------------------------B连接 Key Lock----------------------
INSERT INTO dbo.UserInfo
        ( Name, Age, Mobile, AddTime, Type )
VALUES  ( kkk, -- Name - varchar(50)
          18, -- Age - int
          234, -- Mobile - char(11)
          GETDATE(), -- AddTime - datetime
          7  -- Type - int
          ) --可以执行插入
SELECT * FROM dbo.UserInfo WITH(NOLOCK) --可以执行查询(在一个事务中,有更新字段但还没有提交,此时就会查处脏数据)
SELECT * FROM dbo.UserInfo WITH(NOLOCK) WHERE Name = kkk --可以执行查询

-----//全表查询及操作正在处理的行
SELECT * FROM dbo.UserInfo --需要等待解锁
SELECT * FROM dbo.UserInfo WHERE Id=3 --需要等待解锁(根据主键,但与A连接操作相同行不可)
UPDATE dbo.UserInfo SET Name=mmm WHERE Id=3 --需要等待解锁(根据主键,但与A连接操作相同行不可)
DELETE dbo.UserInfo WHERE Id=3 --需要等待解锁(根据主键,但与A连接操作相同行不可)
-----//使用非主键为条件的操作
SELECT * FROM dbo.UserInfo WHERE Name=aaa --需要等待解锁(非主键不可)
UPDATE dbo.UserInfo SET Name=ooo WHERE Name=aaa --需要等待解锁(非主键不可)
DELETE dbo.UserInfo WHERE Name=aaa --需要等待解锁(非主键不可)
-----//使用主键为条件的操作
SELECT * FROM dbo.UserInfo WHERE id=1 --可以执行查询(根据主键可以)
UPDATE dbo.UserInfo SET Name=yyy WHERE Id=1 --可以执行更新(根据主键可以)
DELETE dbo.UserInfo WHERE Id=1 --可以执行删除(根据主键可以)


索引锁:
结论:
------------------------A连接 Index Lock--------------------
DROP INDEX dbo.UserInfo.Index_UserInfo_Name
CREATE INDEX Index_UserInfo_Name ON dbo.UserInfo(Name)

BEGIN TRAN
UPDATE dbo.UserInfo SET age=66 WHERE Name=ddd --使用name索引列为条件

SELECT resource_type, request_mode,COUNT(*)  FROM sys.dm_tran_locks
WHERE request_session_id=@@SPID
GROUP BY resource_type,request_mode

--ROLLBACK TRAN

----------------------B连接 Index Lock-------------------
INSERT INTO dbo.UserInfo
        ( Name, Age, Mobile, AddTime, Type )
VALUES  ( iii, -- Name - varchar(50)
          20, -- Age - int
          235235235, -- Mobile - char(11)
          GETDATE(), -- AddTime - datetime
          12  -- Type - int
          ) --可以执行插入
SELECT * FROM dbo.UserInfo WITH(NOLOCK) --可以执行查询(在一个事物中,有更新字段但还没有提交,此时就会查处脏数据)
SELECT * FROM dbo.UserInfo WITH(NOLOCK) WHERE Name = kkk --可以执行查询

-----//全表查询及操作正在处理的行
SELECT * FROM dbo.UserInfo --需要等待解锁
SELECT * FROM dbo.UserInfo WHERE Id=4 --需要等待解锁(根据主键,但与A连接操作相同行不可)
UPDATE dbo.UserInfo SET Name=mmm WHERE Id=4 --需要等待解锁(根据主键,但与A连接操作相同行不可)
DELETE dbo.UserInfo WHERE Id=4 --需要等待解锁(根据主键,但与A连接操作相同行不可)
-----//使用非主键非索引为条件的操作
SELECT * FROM dbo.UserInfo WHERE Age=5 --需要等待解锁(非主键不可)
UPDATE dbo.UserInfo SET Name=ooo WHERE Age=5 --需要等待解锁(非主键不可)
DELETE dbo.UserInfo WHERE Age=5 --需要等待解锁(非主键不可)
-----//使用主键为条件的操作
SELECT * FROM dbo.UserInfo WHERE Id=1 --可以执行更新(根据主键可以)
UPDATE dbo.UserInfo SET Name=yyy WHERE Id=1 --可以执行更新(根据主键可以)
DELETE dbo.UserInfo WHERE Id=1 --可以执行删除(根据主键可以)
-----//使用索引为条件的操作
SELECT * FROM dbo.UserInfo WHERE Name=aaa --需要等待解锁(非主键不可)
UPDATE dbo.UserInfo SET Name=ooo WHERE Name=aaa --可以执行更新(根据索引可以)
DELETE dbo.UserInfo WHERE Name=aaa --可以执行删除(根据索引可以)

 

SQLServer2012在查询分析器里面开两个连接

 

插入锁:

结论:“表锁”锁定对该表的SelectUpdateDelete操作,但不影响对该表的Insert操作也不影响以主键Id为条件的Select,所以Select如果不想等待就要在Select后加With(Nolock),但这样会产生脏数据就是其他事务已更新但并没有提交的数据,如果该事务进行了RollBack则取出的数据就是错误的,所以好自己权衡利弊,一般情况下90%以上的Select都允许脏读,只有账户金额相关的不允许。

------------------A连接 Insert Lock-------------------

BEGINTRAN

INSERTINTOdbo.UserInfo

        (Name,Age,Mobile,AddTime,Type)

VALUES  (‘eee‘,-- Name - varchar(50)

          2,-- Age - int

          ‘555‘,-- Mobile - char(11)

          GETDATE(),-- AddTime - datetime

          0  -- Type - int

          )

         

SELECTresource_type,request_mode,COUNT(*)  FROMsys.dm_tran_locks

WHERErequest_session_id=@@SPID

GROUPBYresource_type,request_mode

 

--ROLLBACK TRAN

 

------------------------B连接 Insert Lock------------------------

INSERTINTOdbo.UserInfo

        (Name,Age,Mobile,AddTime,Type)

VALUES  (‘fff‘,-- Name - varchar(50)

          2,-- Age - int

          ‘123‘,-- Mobile - char(11)

          GETDATE(),-- AddTime - datetime

          1  -- Type - int

          )--可以执行插入

         

SELECT*FROMdbo.UserInfo--需要等待解锁

SELECT*FROMdbo.UserInfoWHEREAge=1 --需要等待解锁

SELECT*FROMdbo.UserInfoWHEREId=3 --可以执行查询(根据主键可以)

SELECT*FROMdbo.UserInfoWITH(NOLOCK)--可以执行查询(在一个事务中,有更新字段但还没有提交,此时就会查处脏数据)

SELECT*FROMdbo.UserInfoWITH(NOLOCK)WHEREAge=1 --可以执行查询

UPDATEdbo.UserInfoSETType=5 WHEREName=‘fff‘  --需要等待解锁

DELETEFROMdbo.UserInfoWHEREName=‘fff‘--需要等待解锁

 

更新锁:

结论:“表锁”锁定对该表的SelectUpdateDelete操作,但不影响对该表的Insert操作也不影响以主键Id为条件的Select

-----------------------A连接 Update Lock-----------------------

BEGINTRAN

UPDATEdbo.UserInfoSETName=‘eee‘WHEREAge= 2

 

SELECTresource_type,request_mode,COUNT(*)  FROMsys.dm_tran_locks

WHERErequest_session_id=@@SPID

GROUPBYresource_type,request_mode

 

--ROLLBACK TRAN

 

------------------------B连接 Update Lock------------------------

INSERTINTOdbo.UserInfo

        (Name,Age,Mobile,AddTime,Type)

VALUES  (‘ppp‘,-- Name - varchar(50)

          15,-- Age - int

          ‘666‘,-- Mobile - char(11)

          GETDATE(),-- AddTime - datetime

          9  -- Type - int

          )--可以执行插入

SELECT*FROMdbo.UserInfo--需要等待解锁

SELECT*FROMdbo.UserInfoWHEREName=‘ppp‘--需要等待解锁

SELECT*FROMdbo.UserInfoWHEREId=3 --可以执行查询(根据主键可以)

SELECT*FROMdbo.UserInfoWITH(NOLOCK)--可以执行查询(在一个事务中,有更新字段但还没有提交,此时就会查处脏数据)

SELECT*FROMdbo.UserInfoWITH(NOLOCK)WHEREName=‘ppp‘--可以执行查询

UPDATEdbo.UserInfoSETAge=8 WHEREName=‘ccc‘--需要等待解锁

DELETEdbo.UserInfoWHEREAge= 5 --需要等待解锁

 

主键锁:

结论:“行锁+表锁”锁定对该表的SelectUpdateDelete操作,但不影响对该表的Insert操作也不影响以主键Id为条件的Select

 

------------------------A连接 Key Lock--------------------

BEGINTRAN

UPDATEdbo.UserInfoSETName=‘hhh‘WHEREId=3 --以主键为条件

 

SELECTresource_type,request_mode,COUNT(*)  FROMsys.dm_tran_locks

WHERErequest_session_id=@@SPID

GROUPBYresource_type,request_mode

 

--ROLLBACK TRAN

 

------------------------B连接 Key Lock----------------------

INSERTINTOdbo.UserInfo

        (Name,Age,Mobile,AddTime,Type)

VALUES  (‘kkk‘,-- Name - varchar(50)

          18,-- Age - int

          ‘234‘,-- Mobile - char(11)

          GETDATE(),-- AddTime - datetime

          7  -- Type - int

          )--可以执行插入

SELECT*FROMdbo.UserInfoWITH(NOLOCK)--可以执行查询(在一个事务中,有更新字段但还没有提交,此时就会查处脏数据)

SELECT*FROMdbo.UserInfoWITH(NOLOCK)WHEREName=‘kkk‘--可以执行查询

 

-----//全表查询及操作正在处理的行

SELECT*FROMdbo.UserInfo--需要等待解锁

SELECT*FROMdbo.UserInfoWHEREId=3 --需要等待解锁(根据主键,但与A连接操作相同行不可)

UPDATEdbo.UserInfoSETName=‘mmm‘WHEREId=3 --需要等待解锁(根据主键,但与A连接操作相同行不可)

DELETEdbo.UserInfoWHEREId=3 --需要等待解锁(根据主键,但与A连接操作相同行不可)

-----//使用非主键为条件的操作

SELECT*FROMdbo.UserInfoWHEREName=‘aaa‘--需要等待解锁(非主键不可)

UPDATEdbo.UserInfoSETName=‘ooo‘WHEREName=‘aaa‘--需要等待解锁(非主键不可)

DELETEdbo.UserInfoWHEREName=‘aaa‘--需要等待解锁(非主键不可)

-----//使用主键为条件的操作

SELECT*FROMdbo.UserInfoWHEREid=1 --可以执行查询(根据主键可以)

UPDATEdbo.UserInfoSETName=‘yyy‘WHEREId=1 --可以执行更新(根据主键可以)

DELETEdbo.UserInfoWHEREId=1 --可以执行删除(根据主键可以)

 

 

索引锁:

结论:

------------------------A连接 Index Lock--------------------

DROPINDEXdbo.UserInfo.Index_UserInfo_Name

CREATEINDEXIndex_UserInfo_NameONdbo.UserInfo(Name)

 

BEGINTRAN

UPDATEdbo.UserInfoSETage=66WHEREName=‘ddd‘--使用name索引列为条件

 

SELECTresource_type,request_mode,COUNT(*)  FROMsys.dm_tran_locks

WHERErequest_session_id=@@SPID

GROUPBYresource_type,request_mode

 

--ROLLBACK TRAN

 

----------------------B连接 Index Lock-------------------

INSERTINTOdbo.UserInfo

        (Name,Age,Mobile,AddTime,Type)

VALUES  (‘iii‘,-- Name - varchar(50)

          20,-- Age - int

          ‘235235235‘,-- Mobile - char(11)

          GETDATE(),-- AddTime - datetime

          12  -- Type - int

          )--可以执行插入

SELECT*FROMdbo.UserInfoWITH(NOLOCK)--可以执行查询(在一个事物中,有更新字段但还没有提交,此时就会查处脏数据)

SELECT*FROMdbo.UserInfoWITH(NOLOCK)WHEREName=‘kkk‘--可以执行查询

 

-----//全表查询及操作正在处理的行

SELECT*FROMdbo.UserInfo--需要等待解锁

SELECT*FROMdbo.UserInfoWHEREId=4 --需要等待解锁(根据主键,但与A连接操作相同行不可)

UPDATEdbo.UserInfoSETName=‘mmm‘WHEREId=4 --需要等待解锁(根据主键,但与A连接操作相同行不可)

DELETEdbo.UserInfoWHEREId=4 --需要等待解锁(根据主键,但与A连接操作相同行不可)

-----//使用非主键非索引为条件的操作

SELECT*FROMdbo.UserInfoWHEREAge=5 --需要等待解锁(非主键不可)

UPDATEdbo.UserInfoSETName=‘ooo‘WHEREAge=5 --需要等待解锁(非主键不可)

DELETEdbo.UserInfoWHEREAge=5 --需要等待解锁(非主键不可)

-----//使用主键为条件的操作

SELECT*FROMdbo.UserInfoWHEREId=1 --可以执行更新(根据主键可以)

UPDATEdbo.UserInfoSETName=‘yyy‘WHEREId=1 --可以执行更新(根据主键可以)

DELETEdbo.UserInfoWHEREId=1 --可以执行删除(根据主键可以)

-----//使用索引为条件的操作

SELECT*FROMdbo.UserInfoWHEREName=‘aaa‘--需要等待解锁(非主键不可)

UPDATEdbo.UserInfoSETName=‘ooo‘WHEREName=‘aaa‘--可以执行更新(根据索引可以)

DELETEdbo.UserInfoWHEREName=‘aaa‘--可以执行删除(根据索引可以)

 

SQLServer2012 锁机制测试解析

标签:

原文地址:http://www.cnblogs.com/taiyonghai/p/5674462.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!