首页 > 代码库 > SQL2005中的事务与锁定(三)- 转载
SQL2005中的事务与锁定(三)- 转载
------------------------------------------------------------------------
-- Author : HappyFlyStone
-- Date : 2009-10-03 15:30:00
-- Version: Microsoft SQL Server 2005 - 9.00.2047.00 (Intel X86)
-- Apr 14 2006 01:12:25
-- Copyright (c) 1988-2005 Microsoft Corporation
-- Enterprise Edition on Windows NT 5.2 (Build 3790: Service Pack 2)
-- 转载请注明出处,更多请关注:http://blog.csdn.net/happyflystone
-- 关键字:隔离等级 锁定 意外数据行为 Lock Hint
------------------------------------------------------------------------
在前面的两篇里我从纯理论上把事务相关的知识作了一个梳理,有人看了一定觉得无味了吧,好这一篇我们加入一点T-SQL语句把前面所说有东东关联起来,我们人为产生锁定来理解不同的意外数据行为在不同隔离等级下的表现,顺便再重温一下意外数据行及隔离等级,让大家对交易事务有一个直观的认识。
在进行实例前不得不先介绍一点锁的知识,注意这儿只是简单的说一下,不作深入讨论。我们根据用户访问资源的行为先归纳出几种锁,这几种锁在下面的实例里会出现,它们为:共享锁定、排它锁定、更新锁定及用意向这个限定词限定的三种锁(意向共享、意向排它、意向更新),当当然还有其它的模式,我们在下一篇再说。意向锁的存在是解决死锁的发生,保证进程在申请锁定前确定当前数据是否存在不兼容性的锁定。
先对上面提到的锁作一个简单的描述,更详细的下面再说。
共享锁定发生在查询记录时,直观就是我们select啦,但是并不是只有select才有共享锁定。一个查询记录的语句必须在没有与共享锁定互斥锁定存在或等待互斥锁定结束后,才能设置共享锁定并提取数据(互斥不互斥就是锁的兼容性,这在以后再说明)。
排它锁定发生在对数据增加、删除、修改时,事务开始以后语句申请并设置排它锁定(前提是没有其它互斥锁定存在),以明确告知其它进程对当前数据不可以查询或修改,等待事务结束后其它进程才可以查询或修改。
更新锁定是一个介于共享与排它之间的中继锁定,比如我们带where条件的update语句,在查询要更新的记录时是设置共享锁定,当要更新数据时这时锁定必须由共享锁定升级成更新锁定继而升级为排它锁定,当排它锁定设置成功才可以进行数据修改操作。显然也是要要求在锁升级的过程中没有互斥锁定的存在。简单的理解更新锁定是一个中继闸一样,把升级成排它锁定进程“序列化”,以解决死锁。最后重点说明一下,数据更新阶段是要对数据排它锁定不是更新锁定,不要被字面意思训导哦。
最后说一下在上述锁定模式下的互斥,共享锁定只与排它锁定互斥,更新锁定只与共享锁定不互斥。
在进行具体实例前我们一定要有一个工具来对我们实例过程进行监控,好,下面我写了一个过程,在需要时直接调用就行,过程如下:
Create Proc sp_us_lockinfo --------------------------------------------------------------------- -- Author : HappyFlyStone -- Date : 2009-10-03 15:30:00 -- BLOG : http://blog.csdn.net/happyflystone -- 申明 :请保留作者信息,转载注明出处--------------------------------------------------------------------AS BEGIN SELECT DB_NAME(t1.resource_database_id) AS [数据库名], t1.resource_type AS [资源类型], -- t1.request_type AS [请求类型], t1.request_status AS [请求状态], -- t1.resource_description AS [资源说明], CASE t1.request_owner_type WHEN ‘TRANSACTION‘ THEN ‘事务所有‘ WHEN ‘CURSOR‘ THEN ‘游标所有‘ WHEN ‘SESSION‘ THEN ‘用户会话所有‘ WHEN ‘SHARED_TRANSACTION_WORKSPACE‘ THEN ‘事务工作区的共享所有‘ WHEN ‘EXCLUSIVE_TRANSACTION_WORKSPACE‘ THEN ‘事务工作区的独占所有‘ ELSE ‘‘ END AS [拥有请求的实体类型], CASE WHEN T1.resource_type = ‘OBJECT‘ THEN OBJECT_NAME(T1.resource_ASsociated_entity_id) ELSE T1.resource_type+‘:‘+ISNULL(LTRIM(T1.resource_ASsociated_entity_id),‘‘) END AS [锁定的对象], t4.[name] AS [索引], t1.request_mode AS [锁定类型], t1.request_session_id AS [当前spid], t2.blocking_session_id AS [锁定spid], -- t3.snapshot_isolation_state AS [快照隔离状态], t3.snapshot_isolation_state_desc AS [快照隔离状态描述], t3.is_read_committed_snapshot_on AS [已提交读快照隔离] FROM sys.dm_tran_locks AS t1 left join sys.dm_os_waiting_tasks AS t2 ON t1.lock_owner_address = t2.resource_address left join sys.databases AS t3 ON t1.resource_database_id = t3.database_id left join ( SELECT rsc_text,rsc_indid,rsc_objid,b.[name] FROM sys.syslockinfo a JOIN sys.indexes b ON a.rsc_indid = b.index_id and b.object_id = a.rsc_objid) t4 ON t1.resource_description = t4.rsc_text END GO /*调用示例:exec sp_us_lockinfo */ exec sp_us_lockinfo /*
SQL2005中的事务与锁定(三)- 转载