WAITFOR  time '10:53:00'

解决方案 »

  1.   

    WITH   (UPDLOCK,HOLDLOCK) --加多一个锁保留到事务完成
      

  2.   

    执行完第一个连接马上执行第2个,总是只能更新1行当你的事务提交以后你的锁自然就释放了,不可能说你更新了一行,那么这一行永远都保留更新信息的,你自己想想这样也不合理
    --整理一下,发代码别偷懒
    DECLARE   @id   int   
    BEGIN   TRAN 
      SET   @id   =   0 
      SELECT   TOP   1   @id   =   id 
        FROM   t_73   WITH    (UPDLOCK,HOLDLOCK) 
       WHERE   teacode1   =   ' '     WAITFOR   delay   '00:00:03 '   
      IF   @id   >   0   
      BEGIN 
        UPDATE   t_73 SET     teacode1   =   '1 ' 
         WHERE   id   =   @id   --如果这里没提交,执行第二个是可以更新第二行的,可是提交了锁自然就释放了
    --COMMIT
      

  3.   

    是不合理,
    SET TRANSACTION ISOLATION LEVEL REPEATABLE READbegin transelect * from tablename with (rowlock) where id=3waitfor delay '00:00:05'commit tran
      

  4.   

    这样的结果是正确的.在用这些锁之前要了解这些锁的作用,UPDLOCK一般是可用来防止丢失更新.
    UPDLOCK 
    读取表时使用更新锁,而不使用共享锁,并将锁一直保留到语句或事务的结束。UPDLOCK 的优点是允许您读取数据(不阻塞其它事务)并在以后更新数据,同时确保自从上次读取数据后数据没有被更改。在第一个连接中执行
    SELECT   TOP   1   @id   =   id 
                    FROM   t_73   WITH   (UPDLOCK) 
                    WHERE   teacode1   =   ' '  
    就等于告诉服务器"我将要更新teacode1   =   ' ' 的记录,所有在这条语句后所发出的更新语句(即第二个连接的UPDLOCK语句处)都必须等待,也就是这两个连接是第一个事物执行完后,第二个才开始. 
    当第一个连接执行完了,teacode1 = 1,接着在第二个连接(UPDLOCK)处开始执行,满足teacode1 = ' '的记录没有.所以只有第一个连接更新了.
     
      

  5.   

    楼上正解,用WITH  (UPDLOCK) 把所有teacode1= '   '   的记录都锁定了。
    我如何才能只锁定第一个teacode1= '   '的记录呢?
    我现在没办法只能用的表锁定,还好一个表至多不超过3万行,最多20用户同时操作。
    但是要是只锁定行就更好了。
    操作很简单,2万条teacode1   =   '   ' 的记录,那个客户请求就分配一条记录给客户修改,并做上标记(当前的事务就是完成这个功能,并做成存储过程)。客户修改完毕后再根据返回的id更新数据。
      

  6.   

    不行呀,如果加上 pastread 查询可以,但是以更新也锁死了
      

  7.   

    DECLARE   @id   int   
    BEGIN   TRAN 
      SET   @id   =   0 
      SELECT   TOP   1   @id   =   id 
        FROM   t_73  WITH (UPDLOCK,READPAST)  --加上readpast
       WHERE   teacode1   =   ' '   
       
      WAITFOR   delay   '00:00:10 '   
      IF   @id   >   0   
      BEGIN 
        PRINT(@id)
        UPDATE   t_73 SET     teacode1   =   convert(varchar(10),id)
         WHERE   id   =   @id   
      endcommit tran执行后出现死锁(发生位置在Update处),为什么会这样呢,其实在这里我们忽略了索引对并发的影响.
    在id上建立个索引就可以避免死锁了.