我做了一个进销存软件,入库单号从HL000001开始自动产生,并且是主健。一台机器
录入数据时,没有发生问题,但是如果两台机器同时录入,就会产生错误,(主健冲突)应该如何避免?入库单是主从结构,已入库单号为关联。

解决方案 »

  1.   

    楼上的第一种方法我赞成,但第二种方法我有疑问。试问你怎么得到第二台机器的单据号呢?
    对于第一种方法的补充:
    如果万一产生冲突的话,还可以解决:
    捕获数据库的异常,当异常是主键冲突的话,表示取出的当前号已被占用,你就再重新去取号,并且可以设置重试次数,比如如果重取5次还是冲突的话就让用户稍等会再存盘!有点象ftp登录服务器一样,但不能无限制去重试,否则将加重服务器的负担!如果觉得我的意见可以的话,请适当给我加点分,我就快升级了!呵呵!
      

  2.   

    在BeforePost事件中产生入库单号!这样就不会重复!
      

  3.   

    coolnan(天涯倦客) 的第一条方案最好,我也是这么用的
      

  4.   

    如果你用做的是C/S结构的,并用的是MS SQL SERVER,
    则你可以用一个全局临时表来解决问题,
    在入库单新增时调用一个存储过程,
    在过程中取得最大的编号+1,
    看这个编号有没有全局临时表如:##HL000010,
    如果有则+1后再判断,
    如果没有则用本编号建一个全局临时表如##HL000013,
    临时表的数据列刚好作为明细表的数据缓冲,
    要保存时,还可以用一个存储过程在事务中来处理主细表的同时更新问题。用这个办法的好处是可以事先得到单据编号,并不会冲突,还可以用事务来
    保证数据的一致性。
      

  5.   

    同意 coolnan(天涯倦客)的方案1。并做补充 ( 关于锁定表方案,但如果读表取ID,产生新ID与将其写库不同时进行,锁定是没用的。你可以改进你的程序,锁定表后,将有关表的事务处理在如读表取ID,产生新ID并立即将其写库一并处理,可试试。我也做过类似的程序。同时操作发生冲突机率很小,可改进你的程序。
      

  6.   

    同意liang_z(千山一刀之忍者神龟) 的,不过我觉得没那么复杂,刚好我最近也解决了此类的并发数据采集问题我的解决方法是:在SQL SERVER数据库中写一个申请锁的存储过程,程序运行时,每次都要先申请锁,申请成功则采集。存储过程很简单(如下)
    CREATE PROC P_SetLock 
    @DeptCode VARCHAR(5),
    @RetVal INT OUTPUT
    AS
    BEGIN TRAN
    SELECT @RetVal = Coll_Start_Sign FROM T_DepaInfo WITH(UPDLOCK) WHERE New_Depart_Code=@DeptCode IF @@ERROR <> 0 
    BEGIN
    SET @RetVal = -1
    END IF @RetVal <> 2 AND @RetVal <> 1
    BEGIN
    SET @RetVal = 0
    END
    ELSE
    BEGIN
    SET @RetVal = -1
    END IF @RetVal = 0
    BEGIN
      UPDATE T_DepaInfo SET Coll_Start_Sign = 2 WHERE New_Depart_Code=@DeptCode
    END
    IF @@ERROR <> 0
    BEGIN
    SET @RetVal = -1
    END COMMIT TRAN
      

  7.   

    最简单的办法加以个id字段,类型为uniqueidentifier 默认值是newid()
    一切ok!