SqlServer并发事务(二):锁粒度和锁模式(一)

2015-01-21 11:58:46 · 作者: · 浏览: 13

锁粒度:

资源 格式 说明
DATABASE 不适用 resource_database_id 列中已提供数据库 ID。
FILE 此资源所表示的文件 ID。
Object 此资源所表示的对象 ID。 此对象可以是sys.objects 中列出的任何对象,不仅仅是表。
PAGE : HoBt ID。此值与 sys.partitions.hobt_id 相对应。 PAGE 资源并不总是有 HoBt ID,因为 HoBt ID 是可由调用方提供的额外信息,而有些调用方不能提供该信息。
KEY 表示行中由此资源表示的键列的哈希。HoBt ID。此值与 sys.partitions.hobt_id 相对应。
EXTENT : 表示此资源所表示的区的文件和页 ID。 区 ID 与区中的第一页的页 ID 相同。
RID :: 表示此资源所表示的行的页 ID 和行 ID。 请注意,如果关联的对象 ID 为 99,则此资源表示 IAM 链的第一个 IAM 页上的八个混合页槽之一。HoBt ID。此值与 sys.partitions.hobt_id 相对应。
APPLICATION ::() 表示用于划分此应用程序锁资源范围的数据库主体的 ID。 还包含与此应用程序锁资源相对应的资源字符串,最多包含其中的 32 个字符。 在某些情况下,因不再提供完整字符串而只能显示 2 个字符。 只有在恢复过程中重新获取的应用程序锁处于数据库恢复期间才会发生此行为。 哈希值表示与此应用程序锁资源相对应的完整资源字符串的哈希。
HOBT 不适用 作为 resource_associated_entity_id 提供的 HoBt ID。此值与 sys.partitions.hobt_id 相对应。
ALLOCATION_UNIT 不适用 作为 resource_associated_entity_id 提供的分配单元 ID。此值与 sys.allocation_units.allocation_unit_id相对应。


锁粒度查看测试:

CREATE TABLE mytest(
	id	int,
	name varchar(20),
	info varchar(20)
)

insert into mytest
select 1,'kk',null
union all
select 2,'mm',null

create nonclustered index ix_mytest_name on mytest(name,id)
--create clustered index ix_mytest on mytest(id) 


--	事务的锁资源类型
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
begin tran
	update t set info='kk' from mytest t where ID=1	--OBJECT,PAGE,RID(堆),KEY(聚集索引)
--	update t set info='kk' from mytest t with(rowlock) where ID=1	--OBJECT,PAGE,RID(堆),KEY(聚集索引)
--	update t set info='kk' from mytest t with(paglock) where ID=1	--OBJECT,PAGE
--	update t set info='kk' from mytest t with(tablock) where ID=1	--OBJECT
--	alter table mytest add col int		--DATABASE,METADATA(Sch-S),OBJECT(Sch-M),OBJECT,RID(堆),KEY(聚集索引)

	select resource_type,resource_description,request_mode,request_status,request_type,request_lifetime
	from sys.dm_tran_locks where resource_database_id=DB_ID() and request_session_id=@@SPID
rollback tran


--	事务的锁资源类型
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
begin tran
	alter index ix_mytest_name on mytest rebuild	--几乎包括所有基本类型

	select resource_type,resource_description,request_mode,request_status,request_type,request_lifetime
	from sys.dm_tran_locks where resource_database_id=DB_ID() and request_session_id=@@SPID
rollback tran

--	所有正在请求的资源信息
select request_session_id,resource_type,resource_description,request_mode,request_status,request_type
,request_lifetime,request_owner_type,resource_associated_entity_id,lock_owner_address
from sys.dm_tran_locks where resource_database_id=DB_ID() order by request_session_id

--	根据sys.dm_tran_locks(resource_associated_entity_id)可确定正在锁定的是哪个对象或索引
--(对象正在访问则需等待结束)
select p.partition_id,p.partition_number,OBJECT_NAME(p.object_id) as table_name
,i.name as index_name,i.type_desc,p.rows
from sys.partitions p 
inner join sys.indexes i on p.object_id=i.object_id and p.index_id=i.index_id
where  281474979397632 IN(p.object_id,p.hobt_id)
--即where resource_associated_entity_id IN(p.object_id,p.hobt_id)

摘:

Microsoft SQL Server 数据库引擎具有多粒度锁定,允许一个事务锁定不同类型的资源。为了尽量减少锁定的开销,数据库引擎自动将资源锁定在适合任务的级别。锁定在较小的粒度(例如行)可以提高并发度,但开销较高,因为如果锁定了许多行,则需要持有更多的锁。锁定在较大的粒度(例如表)会降低了并发度,因为锁定整个表限制了其他事务对表中任意部分的访问。但其开销较低,因为需要维护的锁较少。


锁模式:

锁模式

说明

共享 (S)

用于不更改或不更新数据的读取操作,如 SELECT语句。

更新 (U)

用于可更新的资源