当前位置:Gxlcms > 数据库问题 > SQLServer2012 锁机制测试解析

SQLServer2012 锁机制测试解析

时间:2021-07-01 10:21:17 帮助过:2人阅读

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 --

人气教程排行