动手分析SQL Server中的事务中使用的锁( 三 )


request_session_id
resource_type
request_status
request_mode
resource_description
objectName
52
DATABASE
GRANT
S
 
Test
52
PAGE
GRANT
IX
1:280
UserTable
52
OBJECT
GRANT
IX
 
UserTable
52
KEY
【动手分析SQL Server中的事务中使用的锁】GRANT
X
(ead909dc80bf)
UserTable
该事务持有的锁:

  1. 数据库层面的共享锁;
  2. 数据页上的意向排他锁;
  3. 数据表上面的意向排他锁;
  4. 数据行的排他锁;
有了insert的经验后,理解update语句使用的锁难度就不大了 。其与insert使用的锁的类型基本一样,由于本次是使用主键进行修改,数据库可以直接定位到需要进行变更的数据行,因此只需要在对应的行上增加X锁就可以满足事务的需要 。
日常使用的时候很少直接通过id更新数据,往往基于一些非聚集索引更新数据,在这种情况下数据库对于锁的使用会有什么不一样呢?首先针对测试的数据表增加两个索引:
create nonclustered index idx_UserTable_Name on UserTable(name)create nonclustered index idx_UserTable_LastModifyTime on UserTable(lastmodifytime)然后将update语句修改为根据name更新数据:
begin tran set statistics profile on update UserTable set lastmodifytime=GETDATE()where name like '%test%'该语句对应的锁的情况统计:
request_session_id
resource_type
request_status
request_mode
resource_description
objectName
52
DATABASE
GRANT
S
 
Test
52
PAGE
GRANT
IX
1:280
UserTable
52
PAGE
GRANT
IX
1:368
UserTable
52
KEY
GRANT
X
(ba4eae1b81ad)
UserTable
52
KEY
GRANT
X
(500c265deab6)
UserTable
52
KEY
GRANT
X
(a1a185fdb4ae)
UserTable
52
OBJECT
GRANT
IX
 
UserTable
52
KEY
GRANT
X
(ff4928fe375a)
UserTable
52
KEY
GRANT
X
(0ee48b5e6942)
UserTable
可以发现通过非聚集索引更新数据的时候,数据库需要检查的内容明显增加,并且增加IX锁的数据也多了不少 。只看这个表格可能不太好理解,这些key对应的X锁为什么要增加,以及是使用的哪个索引呢?为了了解更多的信息,上文中查询事务锁的语句需要进行一些改动,增加对于索引的关联查询:
with indexs as (SELECT索引名称 = a.name ,表名 = c.name ,索引字段名 = d.name ,a.indidFROMsysindexes aJOIN sysindexkeys b ON a.id = b.idAND a.indid = b.indidJOIN sysobjects c ON b.id = c.idJOIN syscolumns d ON b.id = d.idAND b.colid = d.colidWHEREa.indid NOT IN ( 0, 255 )ANDc.name='UserTable' --查指定表 )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,index_id,i.索引名称 from sys.dm_tran_locks lockleft join sys.partitions p on p.hobt_id=lock.resource_associated_entity_idleft join indexsi on i.indid=index_idorder by lock.request_session_id通过关联查询索引信息,得到了更丰富的内容:
request_session_id
resource_type
request_status
request_mode
resource_description
objectName
index_id
索引名称
52
DATABASE
GRANT
S
 
Test
NULL
NULL
52
PAGE
GRANT
IX
1:280
UserTable
1
PK__Test1__3213E83F133024F3
52
PAGE
GRANT
IX
1:368
UserTable
4
idx_UserTable_LastModifyTime
52
KEY
GRANT
X
(ba4eae1b81ad)
UserTable
4
idx_UserTable_LastModifyTime
52
KEY
GRANT
X
(500c265deab6)
UserTable
4
idx_UserTable_LastModifyTime
52
KEY
GRANT
X
(a1a185fdb4ae)
UserTable
1
PK__Test1__3213E83F133024F3
52


推荐阅读