/**********  加锁   ***************
设table1(A,B,C)
A    B    C
a1   b1   c1
a2   b2   c2
a3   b3   c31)排它锁
新建两个连接
在第一个连接中执行以下语句
begin tran
   update table1
   set A='aa'
   where B='b2'
   waitfor delay '00:00:30'  --等待30秒
commit tran
在第二个连接中执行以下语句
begin tran
   select * from table1
   where B='b2'   
commit tran若同时执行上述两个语句,则select查询必须等待update执行完毕才能执行即要等待30秒2)共享锁
在第一个连接中执行以下语句
begin tran
   select * from table1 holdlock -holdlock人为加锁
   where B='b2' 
   waitfor delay '00:00:30'  --等待30秒
commit tran在第二个连接中执行以下语句
begin tran
   select A,C from table1
   where B='b2' 
   update table1
   set A='aa'
   where B='b2'   
commit tran若同时执行上述两个语句,则第二个连接中的select查询可以执行
而update必须等待第一个连接中的共享锁结束后才能执行 即要等待30秒3)死锁
增设table2(D,E)
D    E
d1   e1
d2   e2
在第一个连接中执行以下语句
begin tran
   update table1
   set A='aa'
   where B='b2' 
   waitfor  delay '00:00:30'
   update table2
   set D='d5'
   where E='e1' 
commit tran
   
在第二个连接中执行以下语句
begin tran
   update table2
   set D='d5'
   where E='e1' 
   waitfor  delay '00:00:10'
   update table1
   set A='aa'
   where B='b2'  
commit tran同时执行,系统会检测出死锁,并中止进程
--------------------------------------------------------------
SET IMPLICIT_TRANSACTIONS  ON --用户每次必须显式提交或回滚。否则当用户断开连接时,
                              --事务及其所包含的所有数据更改将回滚SET IMPLICIT_TRANSACTIONS  OFF --自动提交模式。在自动提交模式下,如果各个语句成功
                               --完成则提交。

解决方案 »

  1.   

    不知道 txlicenhe(马可)兄从哪抄来这么一段?不过,对解决我的问题有什么帮助,我是一点也没看出来。谢谢你的拷贝及粘贴,并希望你关注此问题。期待其他人帮助。
      

  2.   

    问题的焦点出现在:
    update t1 with(rowlock) set b=b+1 where a=45
    这一句,其实根本不是行级锁。是不是这个问题真的解决不了?
    如果是这样,我只能绕道而行了。
      

  3.   

    换句话说:
    我怎么能让
    begin tran(事务一)
    update t1 with(rowlock) set b=b+1 where a=45
    commit tran

    begin tran(事务二)
    update t1 with(rowlock) set b=b+1 where a=23
    commit tran
    各自处理自己的事情,不相互影响。
    我想我已经说得很明白了吧。
    万事具备,只欠高手。
      

  4.   

    楼主参考:
    自定义索引的锁定
    在大多数情况下,Microsoft® SQL Server™ 2000 动态锁定策略自动选择查询的最佳锁定粒度。在访问模式很好理解且一致的情况下,限制索引可用的锁定级别是很有益的。例如,数据库应用程序使用的查找表在批处理进程中每周进行刷新。最有效的锁定策略是关闭页和行锁定,并允许所有并发读取器获得表上的共享 (S) 锁以减少开销。在每周的批处理更新时,更新进程可以使用排它 (X) 锁,然后更新整个表。可以使用 sp_indexoption 系统存储过程来设置用于索引的锁定粒度。若要显示给定索引的当前锁定选项,请使用 INDEXPROPERTY 函数。可以禁止将页级锁、行级锁或二者的组合用于指定的索引。禁止的锁 访问索引的锁 
    页级 行级锁和表级锁 
    行级 页级锁和表级锁 
    页级和行级 表级锁 
    例如,当已知表是争夺点时,禁止页级锁从而只允许行级锁会有好处。或者如果总是使用表扫描来访问索引或表,那么通过只允许表级锁而禁止页级锁和行级锁将会很有帮助。
    重要  SQL Server 查询优化器自动作出正确的决定。建议您不要替代优化器作出的选择。禁止锁定级别反过来会影响表或索引的并发。例如,在由许多用户频繁访问的大型表上只指定表级锁会严重影响性能。用户在访问表之前必须等待释放表级锁。
      

  5.   

    在大多数情况下,SQL Server 2000 动态锁定策略自动选择最佳锁定粒度。
    之所以,楼主认为SQL server 2000的锁定策略与你说的不符,很有可能是因为:
    你的表中没有合适的主键。当一个表没有主键时,数据库就把整行做为主键。
    你用update t1 with(rowlock) set b=b+1 where a=45这样的话,试图来锁定
    a           b           
    ----------- ----------- 
    45          49
    这条记录,其实是不可能的,数据库认为,其它行也可以存在a=45这样的情况,
    所以,他就锁定了整个表。其实,SQL Server 2000 自动选择的锁定粒度是对的,
    只是与你想的不一样而矣。
    解决办法有两个。
    1.把Where a=45改为where a=45 and b=49
    2.把A做为表的主键。(个人以为,这种方法更好一些)
    当然,你上面的Rowlock改过UPDLock可能更好些(因为,粒度是自动选择的,所以,
    我个人以为,可能就不用写RowLock了)
    楼主遇到的情况不知道是不是这样的,反正我以前被这个问题困扰时,就是这样解决的。
    估计差不多。
      

  6.   

    1 如何锁一个表的某一行
    A 连接中执行SET TRANSACTION ISOLATION LEVEL REPEATABLE READbegin transelect * from tablename with (rowlock) where id=3waitfor delay '00:00:05'commit tranB连接中如果执行update tablename set colname='10' where id=3 --则要等待5秒update tablename set colname='10' where id<>3 --可立即执行2 锁定数据库的一个表SELECT * FROM table WITH (HOLDLOCK) 
    注意: 锁定数据库的一个表的区别SELECT * FROM table WITH (HOLDLOCK) 
    其他事务可以读取表,但不能更新删除SELECT * FROM table WITH (TABLOCKX) 
    其他事务不能读取表,更新和删除