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在查询分析器里面开两个连接
插入锁:
结论:“表锁”锁定对该表的Select、Update、Delete操作,但不影响对该表的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 --