如何使SELECT命令筛选的行加锁,不叫别人在SELECT这些行。SELECT * FROM table1 WITH(ROWLOCK) WHERE AutoID = 9我用这个命令执行完,其它的用户还是可以通过这句取过来记录。请高手给于帮助,万分感谢!

解决方案 »

  1.   

    如何使SELECT命令筛选的行加锁,不叫别人在SELECT这些行。 SELECT * FROM table1 WITH(ROWLOCK) WHERE AutoID = 9 我用这个命令执行完,其它的用户还是可以通过这句取过来记录。 请高手给于帮助,万分感谢!
      

  2.   

    你想要永久的锁定这行数据?
    那么你干嘛不干脆把它删除了?
    真的要锁,你可以写一个事务长时间持有该锁。
    不过你即使设定了排他锁,其他人还是可以用with nolock来进行读取。你的实际意图是?
      

  3.   

    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 
    SELECT * FROM table ROWLOCK WHERE id = 1 
    http://www.cnblogs.com/Ace2009/archive/2009/01/06/1370218.html
      

  4.   

    看一下吧:http://www.cnblogs.com/Ace2009/archive/2009/01/06/1370218.html
      

  5.   


    表 table1
    AutoID   A2   A3
    1        66   9
    2        77   9
    3        88   9我读到过来第二条记录,在本地进行计算,将计算的值更新到第二条记录上。
    SELECT * FROM table1 WITH(ROWLOCK) WHERE AutoID = 2
    这个区间要在本地计算.......
    UPDATE table1 SET A2 = xxxx, A3 = xxxx WHERE AutoID = 2当我在本地计算时,别人也用SELECT取了这条记录,也在本地计算。
    这就出了问题了用表级排它锁可以解决在SELECT后不叫别人用SELECT,这样效率低。
    因为另一个用户要操作的是AutoID=3也被堵塞了,要等到操作AutoID=2的事务结速。[wuyq11]朋友说的,我以经试过了,不行啊。
      

  6.   


    这里用的是UPDLOCK
    SELECT * FROM table1 WITH(UPDLOCK) WHERE AutoID = 9 这样也不行,把整个表都锁了,我试过了。
      

  7.   

    SET   LOCK_TIMEOUT   1000   
        
      begin   tran   TranName   
        
      select   *   from   tablename   WITH   (updlock)   where...   
          
      waitfor   delay   '00:00:05'   
        
      commit   Tran   TranName   只锁定5秒
      

  8.   


    首先, SELECT * FROM table1 WITH(ROWLOCK) WHERE AutoID = 9 ,这句在执行的过程中所选行是被锁住的。
    但是这条语句结束后,这个所就被释放了。其次, 在数据库里面加锁的代价是非常昂贵的,建议能不用就不用。所以,如果你想实现执行完某个sql之后某些行就不可用了, 我还是建议你,在这个表增加一个column [Available] bit,
    需要某些行不可用时就把该行的[Available]设成0, 其它sql从这个表select的时候就加一个where [Available]=1.
      

  9.   


    begin  tran 
    select * from tb WITH(UPDLOCK, READPAST) where id = 1 
    waitfor  delay  '00:00:20'  
    print 'ok'
    commit  begin  tran 
    select * from tb WITH(UPDLOCK, READPAST) where id = 2 
    waitfor  delay  '00:00:03'  
    print 'ok'
    commit  Tran
    你可以试一下两者并发执行的效果。
      

  10.   


    先谢谢这位朋友.这样还是不能完成我的需求.这样是可以实现,可是第二的用户取不过来数据了,而不是等待第一个用户释放锁.
    这样也会出现错误的,因为这条记录确是存在的,第二个用户SELECT完认为不存在,会增加这样的记录.
    结果表里就会出现重复.
      

  11.   

    SELECT * FROM table1 WITH(ROWLOCK) WHERE AutoID = 9 with(lock)
      

  12.   

    八 几个有关锁的问题 1 如何锁一个表的某一行 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED SELECT * FROM table ROWLOCK WHERE id = 1 2 锁定数据库的一个表 SELECT * FROM table WITH (HOLDLOCK) 加锁语句: 
    sybase: 
    update 表 set col1=col1 where 1=0 ; 
    MSSQL: 
    select col1 from 表 (tablockx) where 1=0 ; 
    oracle: 
    LOCK TABLE 表 IN EXCLUSIVE MODE ; 
    加锁后其它人不可操作,直到加锁用户解锁,用commit或rollback解锁 
    几个例子帮助大家加深印象 
    设table1(A,B,C) 
    A B C 
    a1 b1 c1 
    a2 b2 c2 
    a3 b3 c3 1)排它锁 
    新建两个连接 
    在第一个连接中执行以下语句 
    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 同时执行,系统会检测出死锁,并中止进程 补充一点: 
    Sql Server2000支持的表级锁定提示 HOLDLOCK 持有共享锁,直到整个事务完成,应该在被锁对象不需要时立即释放,等于SERIALIZABLE事务隔离级别 NOLOCK 语句执行时不发出共享锁,允许脏读 ,等于 READ UNCOMMITTED事务隔离级别 PAGLOCK 在使用一个表锁的地方用多个页锁 READPAST 让sql server跳过任何锁定行,执行事务,适用于READ UNCOMMITTED事务隔离级别只跳过RID锁,不跳过页,区域和表锁 ROWLOCK 强制使用行锁 TABLOCKX 强制使用独占表级锁,这个锁在事务期间阻止任何其他事务使用这个表 UPLOCK 强制在读表时使用更新而不用共享锁 应用程序锁: 
    应用程序锁就是客户端代码生成的锁,而不是sql server本身生成的锁 处理应用程序锁的两个过程 sp_getapplock 锁定应用程序资源 sp_releaseapplock 为应用程序资源解锁 注意: 锁定数据库的一个表的区别 SELECT * FROM table WITH (HOLDLOCK) 其他事务可以读取表,但不能更新删除 SELECT * FROM table WITH (TABLOCKX) 其他事务不能读取表,更新和删除 
    =========================================
    于行锁,我觉得不太好,因为,在更新库存时,有可能某个进程正在更新该材料的其他信息。如果采用行锁的话,会锁定其他的修改请求。 
     
    那就锁表. 
    参考如下: 1 如何锁一个表的某一行 A 连接中执行 SET TRANSACTION ISOLATION LEVEL REPEATABLE READ begin tran select * from tablename with (rowlock) where id=3 waitfor delay '00:00:05' commit tran B连接中如果执行 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) 
    其他事务不能读取表,更新和删除
      

  13.   

    难道SQL Server就没有锁行的概念????????这种情况应该总会用到的.我说一下我现在的需求.收发主表
    收发子表
    现存量表
    批次表在一张业务单据过帐时,会登记收发主表与子表,
    根据单据收发数量更新现存量表,在更新批次表.比如在采购入库时,
    更新批次表,先查这条入库批次是否存在,如果存在则更新,
    如果不存在,要增加一条新批次记录.
    (注:这样作是因为出库时用户要选择先进先出、后进先出或手工指定的。)我现在只好用表锁了,现在只有十多个用户,
    正常情况下这些用户感觉不出来等待。
    我怕以后用户增加,或其它问题,会使整个系统瘫痪,必须都重新启动软件,才可使用。
      

  14.   

    八 几个有关锁的问题 1 如何锁一个表的某一行 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED SELECT * FROM table ROWLOCK WHERE id = 1