update tablename with(tablock) set ^………… where ……

解决方案 »

  1.   

    <<应该在某个地方设置一个读表的标志。所有用户读表前都访问此标志。如1 可以读你想读的表了,0 则不可以读!
    设置锁表不太好。>>
    我现在就是用这种方法进行锁定的。但是当两个客户端同时更新同一张表时,虽然这种可能性很小,但一旦发生则会导致数据紊乱。请教能有办法避免这种情况发生吗?
      

  2.   

    <<update tablename with(tablock) set ^………… where ……>>
    这种方法我没用过,想请教下INSERT与DELETE语句中也能这样引用吗,另外锁定表之后,其他客户端是不是不能 SELECT FROM TABLENAME。
      

  3.   

    1 你用事务操作的话,不会有那种情况
    2 你想用2的话,最好用 with (holdlock)
      注意 这种得话,你所有涉及这个表的情况都应考虑到HOLDLOCK 共享锁  将共享锁保留到事务完成,而不是在相应的表、行或数据页不再需要时就立即释放锁
    tablock  排它锁  该锁可以防止其它事务读取或更新表,并在语句或事务结束前一直持有。
      

  4.   

    谢谢ghostzxp(幽灵),我想我的问题提错了。应该是这样,举个例子,有两张表:表1、表2,表1中的字段1为表2中的字段2的外键,要删除表1中的某行需先检查所在行字段1的值在表2的字段2中是否存在,若存在则不能删除。假设一客户端作删除表1中字段1的值为TEST的记录(设定表2字段2在这之前无值为TEST的记录),而同时另一客户端作增加表2字段2的值为TEST的记录,结果是表1中删除了值为TEST的记录,而表2中增加了值为TEST的记录。显然这是不正确的。像这种情况是不是要用分布式事务?
      

  5.   

    PB 中 SQLCA.AutoCommit = True自动提交事物应该选择 True 不知道VB 中怎么处理
      

  6.   

    可用触发器操作
    尽量让sqlserver自己管理
    他会自动加锁的
      

  7.   

    更新语句本身已经自带更新锁,在更新过程中,也是无法查询的。为什么你还要加进去呢?
    给你做个例子直观点:
    --建表
    create table tb(id int)
    insert into tb select 1
    union all select 2--在连接A中运行
    begin tran
    update tb set id=3 where id=1
    waitfor delay '00:00:30'
    commit tran--在连接B中运行
    update tb set id=10 where id=2--结果:由于连接A中的排它锁存在,连接B中的更新语句30秒后才能运行测试二:
    --连接A同上
    --连接B中
    select * from tb--结果:同样的,连接B中的查询也得等到A中更新语句执行完为止
      

  8.   

    谢谢 yjdn(无尽天空) 的详细解答,但你举的例子说明两个客户端在更新同一张表时,SQL会自动锁定,而我的问题是有两张表,表1(DEMOCODE,DEMONAME),表2(DEMOCODE,TESTCODE,TESTNAME)
    当客户端B在更新表2时,限制客户端A对表1的更新。