hi all!
问题:1 当a用户增加一条数据的时候 自动获得一条单据编号(表中纪录条数) 在a用户没保存记录的时候 b用户又在增加一条单据 这时候怎么确保 分配给b用户的编号是没有分配给a用户的 换句话说怎么锁定a获得的纪录编号不被其他用户获得?(锁定字段内容)
      2 怎么样判断当一条单据正在被修改 而其他用户也要修改时就提示该纪录已经被签出修改?(锁定纪录)
      3 当一个表被一个用户使用时 其他用户不能使用这个表 ??(锁定表) 我记得服务器会纪录哪个表所处状态的 但忘了怎么获取这信息的了
谢谢!

解决方案 »

  1.   

    锁的类型有三:共享锁,更新锁,独占锁
    共享锁可以和其他共享锁,更新锁兼容共存
    只有独占锁是不和其他兼容的,所以只要数据上有独占锁,其他用户则不能读写
    在缺省情况下,数据库的默认的锁定粒度是数据页,如果想使其变成表级锁
    可以用holdlock关键字,比如语句
    update titles set ...   holdlock
    这个语句就起用了表级锁,在用户更新这个数据表的时候,其他用户不能读写
    解锁只能等对这个表操作的事务完成了,锁就解开了.缺省时,插入行级锁定是关闭的。但可以在数据库级或表级用sp_tableoption
    存储过程来打开它。例如,为了打开titles表的行级锁定。可执行如下命令:
       sp_tableoption 'titles','insert row rock','true'
    为了打开数据库中的所有已存在的表的行级锁定,可执行如下命令:
       sp_tableoption '%.%','insert row rock','true'注意   sp_tableoption命令会为所有随后的用户事务设置插入表的行级锁定的开
    或关。要想在一个应用程序中动态地起用或禁止行级锁定,可使用dbcc rowlock
    命令:
       dbcc rowlock (dbid,tableid,0/1)例如,要打开pubs数据库中titles表的插入行级锁定,可执行如下程序:
       declare @dbid int,@tableid,int
       select @dbid=db_id("pubs"),@tableid=object_id("titles")
       dbcc rowlock (@dbid,@tableid,1)
    而要关闭pubs数据库中titles表的插入行级锁定,可执行如下程序:
       declare @dbid int,@tableid,int
       select @dbid=db_id("pubs"),@tableid=object_id("titles")
       dbcc rowlock (@dbid,@tableid,0)注意在使用dbcc rowlock命令打开或关闭行级锁定时,其作用一直保留
    至以后的所有用户,直至再次以dbcc rowlock命令重新打开或关闭。出于
    这一原因,在使用这一命令后,要记住在事务完成后立即将其取消或重新
    打开。
    没有足够的理由,锁最好由SQL自己控制,不要去更改锁
     
      

  2.   

    如果是使用SQL Server,在编号没有特殊要求的情况下一般使用GUID作为编号:
    Delphi中:
    var
      NewID:TGUID
    begin
      CreateGUID(NewID);
      //.......
    end;
    在编号有特殊要求的情况下:
    用户登陆后,根据唯一的用户ID创建局部临时表,利用日期和时间生成唯一字段,在表中存储计数器。
    客户端可以通过编号规则、唯一字段、计数器组合创建编号,具体情况视编号规则而定、
    当然为了最大程度防止不唯一编号,在提交的时候应使用事务
      

  3.   

    方法有很多:
    编号产生的规则不一样,:每一客户端加一个pos_id, (如00001)
    产生编号按pos_id+流水号(系统产生);
    别一种在单据印制一个编号,系统产生一个编号。
      

  4.   

    我说一下我的解决方案吧。
    你说的问题无非就是单据编号连续问题,写那么多,差点没兴趣看了。~~
    在记录 Append 时,就给单号,我的主要工作都写在生成单号的 SP 上。有一个表 MaxBill 用来保存最大单号,字段有 MaxBillNo 和 bUseFlag 用于保存最大单号和是否使用标志。取单号是 bUseFlag 默认是0,默认没有使用,一旦有使用,则将该标志改为1。同时在所有客户端保存时检查标志是否重复,如果没有,则使用,否则重新取。
      

  5.   

    wychero(高天) 的方法可取,赞。
      

  6.   

    能不能就是分给了一个客户端的编号就能保证他保存的时候能用这个编号保存 也就是锁住分配出去的编号。。我觉得这个问题不太好解决!假如A用户编号为1,B用户编号为2,B保存,A放弃,这个时候,编号就会产生不连续。你在增加新数据的时候,要么从最大编号开始往后加,要么就是先进行优先补缺号,都要重复的访问表。我处理的办法是在提交之前,作一次检查,如果编号已被使用,则自动往后加,直至没有使用为止,反之直接提交数据!这样可以保证编号的唯一,弊端就是每次提交都要查询,数据量大的时候会影响速度!
      

  7.   

    那样的编号太局限性了,比如说我要@+YYYYMMDD+‘00001‘,数据库自增行么?
      

  8.   

    我也作过同cjs5210(我是菜鸟)一样方法,弊端就是每次提交都要查询,数据量大的时候会影响速度! 也做过先不取编号,存时取编号,但这样不直观了。也试过表保存,不过每次都要去更新加一个表。如果单据号码不要求统一的话。可根椐机器(设一个对照表)生成单据号,每个用户只能一次打开应用系统,这样号码就没问题。不过如要统一的话.....
      这自动编号与自动补号与共享数据冲突还真的很麻烦 ,听高手结合实际讲讲课。
       三种锁的介绍 还是学到不少东西,不过我从来都没有用过.