由于Select语句在SQL Server的默认事务隔离级别(read commited)中执行完成后就会释放相关的锁,而非等到事务结束,在这种情况下无法通过sp_lock或者sys.dm_tran_locks视图观察select语句执行过程中锁的执行情况,因此比较方便的办法是在查询语句执行之前调整当前会话的事务隔离级别为repeatable read,在这个隔离级别中select语句默认会在事故执行完成后提交,比较方便分析 。
在SQL Server Manager Studio的查询窗口中执行语句:
set transaction isolation level repeatable readset statistics profile on begin transelect * from usertable whereid='5E4B68B0-71B8-43FB-B6B4-8E9D43A30589'
在前面的事务目前是已经执行未提交的状态,此时可以通过dm_tran_locks查询到该语句目前持有的锁:
select request_session_id,resource_type,request_status,request_mode,resource_description,case resource_typewhen 'Page' then OBJECT_NAME(p.object_id)when 'object' then OBJECT_NAME(lock.resource_associated_entity_id)when 'database' then (select name from master..SysDatabases where dbid=resource_database_id)when 'key' then object_name(p.object_id)end as objectName from sys.dm_tran_locks lockleft join sys.partitions p on p.hobt_id=lock.resource_associated_entity_idorder by lock.request_session_id
resource_type
request_status
request_mode
resource_description
objectName
62
DATABASE
GRANT
S
Test
62
PAGE
GRANT
IS
0.236111111
UserTable
62
OBJECT
GRANT
IS
UserTable
62
KEY
GRANT
S
(0ee48b5e6942)
UserTable
查询结果字段说明:
- request_session_id:会话编号
- resource_type:被锁定的资源类型
- request_status:请求的状态
- request_mode:锁类型
- resource_description 资源描述情况
- objectName:对象名称
- 通过目前的查询结果可以看到在DATABASE上加了S锁(数据库名为Test);
- 在数据所属的页上增加了意向共享锁;
- 表上增加了意向共享锁;
- 数据行上增加了共享锁;
SQL Server执行insert时使用的锁首先在事务中执行insert语句并且不提交(注意将上个章节中的事务提交):
begin traninsert into UserTable (id,code,name,createtime,lastmodifytime)values(newid(),'test2','测试用户2',getdate(),getdate())
insert的时候默认会有事务,因此主动声明一个事务并只执行不提交就可以很容易地查到当前会话持有的锁 。通过dm_tran_locks查询到该语句目前持有的锁:
resource_type
request_status
request_mode
resource_description
objectName
70
DATABASE
GRANT
S
Test
70
PAGE
GRANT
IX
1:280
UserTable
70
OBJECT
GRANT
IX
UserTable
70
KEY
GRANT
X
(c75ad92ba798)
UserTable
该事务持有的锁:
- 数据库层面的共享锁;
- 数据页上的意向排他锁;
- 数据表的意向排他锁;
- 数据行的排他锁;
SQL Server执行update时使用的锁首先在数据库中执行update语句而不提交(注意将上个章节中的事务提交或者回滚):
begin tran update UserTable set lastmodifytime=GETDATE()where id ='06757850-68D6-416C-B3D1-FD3B29BAD4BB'
通过dm_tran_locks查询到该语句目前持有的锁:
推荐阅读
- 用Stream实现mysql的groupBy, sum Case when 语法
- 经典SQL语句大全
- 国内地下铲运机市场分析 地下铲运机
- 孩子生活自理能力差的原因,孩子生活自理能力差的原因分析
- 招聘|高薪直聘:挪威情报局公开招聘懂中文的网络分析师
- 控制不住笑的原因分析
- 孩子动手打人家长怎么教育?父母打骂孩子犯什么法
- 小学五年级语文单元测试家长评语分析?这样给小学五年级学生作文写评语_1
- 属鼠蓝和属鼠灰人物分析?属鼠蓝和属鼠灰的故事
- 在客户关系管理里,对于客户价值的分析与评价?客户服务与管理期末试题