c表中的fnumber出现重复,因为2个过程都同时执行,获取的maxnum和danjutou值都一样,所以才重复。
你的隔离级别是0 ?

解决方案 »

  1.   

    改成这样试试:declare @maxnum int;
    declare @danjutou varchar(10);
    declare @maxdanju varchar(20);
    BEGIN TRANSACTION
    Begin
    /*
    select @maxnum=maxnum from a where id=112;   ----标志1
    select  @danjutou=danjutou from b where id=888;
    set @maxdanju=@danjutou+@maxnum;
    */
    update a set maxnum=(select maxnum from a where id=112)+1 where id=112;  ---标志2
    update c set fnumber=(select maxnum from a where id=112)+ 
                         (select danjutou from b where id=888)
    where id=***;
    End
    commit TRANSACTION
      

  2.   

    这个需要怎么设置吗?
    我一直以为SQL SERVER默认的是READ COMMITTED
      

  3.   

    你的maxnum没有经过计算,应该不会有问题,除非你两个sp同时传入相同的id
      

  4.   

    生产环境中的存储过程比这个复杂,而且这个存储过程是套在另一个存储过程XX当中,而XX也启用了事务当然工作逻辑是这样没错。
      

  5.   

    问题是其他地方还需要用到@maxnum ,@danjutou,@maxdanju
      

  6.   


    哦,试试这个,加了updlock,也就是更新锁:
    declare @maxnum int;
    declare @danjutou varchar(10);
    declare @maxdanju varchar(20);
    BEGIN TRANSACTION
    Begin
    select @maxnum=maxnum from a with(xlock) where id=112;   ----标志1
    select  @danjutou=danjutou from b with(xlock) where id=888;
    set @maxdanju=@danjutou+@maxnum;
    update a set maxnum=@maxnum+1 where id=112;  ---标志2
    update c set fnumber=@maxdanju where id=***;
    End
    commit TRANSACTION
      

  7.   

     同一个id,在获取max时,在其中一个提交之前,应该不能读取吧。 read commit模式怎么会出现最后一致的数据
     会不会是这个类型
     3+5=8
     
     4+4=8
     因为你是2个参数,获取的最大值相加的结果
      

  8.   

    不是,其实生产环境是这样的:
    A表存单据类型及各单据类型(如出库单)的最大单据编号的数字部分,比如00235
    B表存各单据类型最大单据的完整编号,比如TX00235
    C表存单据的完整信息,如编号、部门、产品等生成编号时是先从A表取出库单类型的最大编号。并储存在临时字段中,值是TX00235
    再将00235+1的值00236写回A表
    再将TX00236写回B表
    再将包括TX00235在内的一些信息插入到C表。
      

  9.   

    这逻辑跟你写的代码不太一样啊,set @maxdanju=@danjutou+@maxnum;