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

2015-01-21 11:58:46 · 作者: · 浏览: 16
中。防止当多个会话在读取、锁定以及随后可能进行的资源更新时发生常见形式的死锁。

排他 (X)

用于数据修改操作,例如 INSERT、UPDATE或 DELETE。确保不会同时对同一资源进行多重更新。

意向

用于建立锁的层次结构。意向锁包含三种类型:意向共享 (IS)、意向排他 (IX)和意向排他共享 (SIX)。

架构

在执行依赖于表架构的操作时使用。架构锁包含两种类型:架构修改 (Sch-M)和架构稳定性 (Sch-S)。

大容量更新 (BU)

在向表进行大容量数据复制且指定了 TABLOCK 提示时使用。

键范围

当使用可序列化事务隔离级别时保护查询读取的行的范围。确保再次运行查询时其他事务无法插入符合可序列化事务的查询的行。


--当前表记录(只有非聚集索引ix_mytest_name)
select * from mytest
id	name	info
1	kk		NULL
2	mm		NULL

create nonclustered index ix_mytest_name on mytest(name) with(drop_existing=on)

--事务1
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
begin tran
	select * from mytest 
	
	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
	
	update t set info='kk' from mytest t where name='kk'
	
	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
--	waitfor delay '00:30:00'
rollback tran

\

<??http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KCjxwPjwvcD4KPHA+PHN0cm9uZz7LtcP3Ojwvc3Ryb25nPjwvcD4KPHA+z8jWtNDQsunRr8qxo6zV+7j2se3Oqrmyz+3L+KOoU6OpoaO909fFvfjQ0Lj80MKy2df3o6zU2rj0wOu8trHwc2VyaWFsaXphYmxl1tCjrLLp0a+74b2rttTP88n9vLbOqsXFy/vL+KGjtvjI57n7xuTL+8rCzvHSstPQubLP7cv4o6y+zbK7xNzXqs6qxcXL+8v4o6zL+dLUyv2+3b/i0v3Tw8HLuPzQwsv4oaO1sdK7uPbKws7x09DBy7j80MLL+KOsxuTL+8rCzvG+zbK7xNzU2cnqx+u4/NDCy/iho9XiuPbKws7xvs3V/bOjyf28ts6qxcXL+8v4vfjQ0LLZ1/ejrLHcw+LBy8vAy/i/ycTco6jI57y4uPbKws7xtrzTtdPQubLP7cv4o6y2vLTyy+O9+NDQxcXL+7LZ1/ejrNXi0fm+zc/gu6W1yLT9s8nLwMv4o6mho9TaubLP7cGjtsi9z7TztcSx7deqseTOqrj80MLBo7bIvc/QobXEttTP88qxo6y+zbvhsvrJ+rmyz+3S4s/yxcXL+8v4o6hTSVijqaGj1rvT0LHt1tDT0Mv30v2yosfS0OjSqrLp0a+8/MHQo6jI525hbWU9"kk'),就会产生键范围锁(RangeS-U),在表共享锁转到键锁过程,对表个层次的粒度都加了相应的锁。


如下表格:锁粒度递增,锁模式更低。


粒度

锁类型

KEY

RangeS-U

KEY

RangeS-U

RID

X

PAGE

IU

PAGE

IX

OBJECT

SIX

DATABASE

S


要检验上面的粒度是否存在锁,先运行上面的【事务1】,等待30分钟再结束。接着再打开另一个查询窗口,逐条执行下面的【事务2】。

--事务2
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
begin tran
	select name from mytest where name='kk'		--KEY(RangeS-U)
--	select id from mytest where name='kk'		--RID(X)
--	select name from mytest where name='mm'		--PAGE(IU)
--	select id,name from mytest where name='mm'	--PAGE(IX)
--	select * from mytest 						--OBJECT(SIX)
--	create table t(id int)						--DATABASE(S)
	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

上面可以验证【事务1】在各个级别粒度是否加锁。


意向锁:

摘:

数据库引擎使用意向锁来保护共享锁(S锁)或排他锁(X锁)放置在锁层次结构的底层资源上。意向锁之所以命名为意向锁,是因为在较低级别锁前可获取它们,因此会通知意向将锁放置在较低级别上。

意向锁有两种用途:

防止其他事务以会使较低级别的锁无效的方式修改较高级别资源。

提高数据库引擎在较高的粒度级别检测锁冲突的效率。

例如,在该表的页或行上请求共享锁(S锁)之前,在表级请求共享意向锁。在表级设置意向锁可防止另一个事务随后在包含那一页的表上获取排他锁(X锁)。意向锁可以提高性能,因为数据库引擎仅在表级检查意向锁来确定事务是否可以安全地获取该表上的锁。而不需要检查表中的每行或每页上的锁以确定事务是否可以锁定整个表。

\

意向锁不多说明了,上面是操作也出现过,具体参考文档吧

大容量更新锁查看测试:

大容量更新锁是在大容量操作时才出现,一下测试查看

--先创建表
select c.name tablename,c.name columnname, o.object_id,c.column_id,o.type,o.type_desc 
into bulkTest
from sys.objects o,sys.columns c 
where 1<>1

select * from bulkTest

--导出测试数据.
exec sp_configure 'show advanced options',1	--启用高级配置选项设置
reconfigure;
exec sp_configure 'xp_cmdshell',1	--启用xp_cmdshell
reconfigure;

--必须放在同一行执行
EXEC master..xp_cmdshell 'bcp "select c.name tablename,c.name columnname, o.object_id,c.column_id,o.type,o.type_desc from sys.objects o,sys.columns c" queryout C:\Users\Administrator\Desktop\bulkTest.txt -c -t"|" -r "\n" -Slocalhost -Usa -Psa'  

--测试用,无需记录大量日志
ALTER DATABASE [mytest] SET RECOVERY SIMPLE WITH NO_WAIT
--ALTER DATABASE [mytest] SET RECOVERY BULK_LOGGED WITH NO_WAIT

提示:
若指定TABLOCK提示,大容量操作将不锁表,这样可以并发插入数据,当然要求 系统性能好,对数据约束不高的情况.
若不指定TABLOCK,系统默认锁住整个表,进行大容量操作.

--好了,开始操作!!打开一个查询窗口,执行以脚本
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

BEGIN TRAN
	B