1、Sql Server2000 支持的表级锁定提示HOLDLOCK 持有共享锁,直到整个事务完成,应该在被锁对象不需要时立即释放,等于 SERIALIZABLE 事务隔离级别 NOLOCK 语句执行时不发出共享锁,允许脏读 ,等于 READ UNCOMMITTED 事务隔离级别 PAGLOCK 在使用一个表锁的地方用多个页锁 READPAST 让 sql server 跳过任何锁定行,执行事务,适用于 READ UNCOMMITTED 事务隔离级别只跳过 RID 锁,不跳过页,区域和表锁 ROWLOCK 强制使用行锁 TABLOCKX 强制使用独占表级锁,这个锁在事务期间阻止任何其他事务使用这个
2、表 UPLOCK 强制在读表时使用更新而不用共享锁 应用程序锁: 应用程序锁就是客户端代码生成的锁,而不是 sql server 本身生成的锁 处理应用程序锁的两个过程 sp_getapplock 锁定应用程序资源 sp_releaseapplock 为应用程序资源解锁 注意: 锁定数据库的一个表的区别 SELECT * FROM table WITH (HOLDLOCK) 其他事务可以读取表,但不能更新删除 SELECT * FROM table WITH (TABLOCKX) 其他事务不能读取表,更新和删除 SQL Server 2005 中解决死锁问题 数据库操作的死锁是不可避免的,本文
3、并不打算讨论死锁如何产生,重点在于解决死锁,通过 SQL Server 2005, 现在似乎有了一种新的解决办法。 将下面的 SQL 语句放在两个不同的连接里面,并且在 5 秒内同时执行,将会发生死锁。 use Northwind begin tran insert into Orders(CustomerId) values(#ALFKI#) waitfor delay #00:00:05# select * from Orders where CustomerId = #ALFKI# commit print #end tran# SQL Server 对付死锁的办法是牺牲掉其中的一个,抛
4、出异常,并且回滚事务。在 SQL Server 2000,语句一旦发生异常,T-SQL 将不会继续运行,上面被牺牲的连接中, print #end tran#语句将不会被运行,所以我们很难在 SQL Server 2000 的 T-SQL 中对死锁进行进一步的处理。 现在不同了,SQL Server 2005 可以在 T-SQL 中对异常进行捕获,这样就给我们提供了一条处理死锁的途径: 下面利用的 try . catch 来解决死锁。 SET XACT_ABORT ON declare r int set r = 1 while r 0 begin declare ErrorMessage n
5、varchar(4000); declare ErrorSeverity int; declare ErrorState int; select ErrorMessage = ERROR_MESSAGE(), ErrorSeverity = ERROR_SEVERITY(), ErrorState = ERROR_STATE(); raiserror (ErrorMessage, ErrorSeverity, ErrorState ); end 我希望将来 SQL Server 2005 能够直接抛出原有异常,比如提供一个无参数的RaiseError。 因此方案有点臃肿,但将死锁问题封装到 T
6、-SQL 中有助于明确职责,提高高层系统的清晰度。现在,对于 DataAccess 的代码,或许再也不需要考虑死锁问题了。 再给一个. 锁定记录,只允许单用户修改的例子 create table #锁表(编号 int) -代码: if exists(select 1 from 编号=你的编号) return insert #锁表 values(你的编号) .你处理的代码 delete #锁表 where 编号=你的编号 - -为了防止死锁,建议加时间: create table #锁表(编号 int,时间 datetime) -代码: if exists(select 1 from 编号=你的
7、编号 and datediff(ss,时间,getdate()5 -如果锁的时候超过 5 秒,则是处理超时 ) return delete from #锁表 insert #锁表 values(你的编号,getdate() .你处理的代码 delete #锁表 where 编号=你的编号 - -锁定记录,只允许单用户修改的例子: -创建测试环境 -创建测试表-部门表 create table 部门(departmentid int,name varchar(10) -记录锁定表 create table lock(departmentid int,dt datetime) go -因为函数中不
8、可以用 getdate,所以用个视图,得到当前时间 create view v_getdate as select dt=getdate() go -创建自定义函数,判断记录是否锁定 create function f_chk(departmentid int) returns bit as begin declare re bit,dt datetime select dt=dt from v_getdate if exists(select 1 from lock where departmentid=departmentid and datediff(ss,dt,dt) 5) set r
9、e=1 else set re=0 return(re) end go -数据处理测试 if dbo.f_chk(3)=1 print 记录被锁定 else begin begin tran insert into lock values(3,getdate() update 部门 set name=A where departmentid=3 delete from lock where departmentid=3 commit tran end -删除测试环境 drop table 部门 drop view v_getdate drop function f_chkhttp:/ 技术资源