CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  MS-SQL Server >  疑难问题

sql2000表死锁

楼主eason2000(eason)2006-12-04 18:20:43 在 MS-SQL Server / 疑难问题 提问

一业务系统,在进行业务处理的时候,都调用以下存储过程,来取得单据序号(recnum),同时进行业务处理时出现表死锁。有什么方法解决?  
  SET   QUOTED_IDENTIFIER   OFF    
  GO  
  SET   ANSI_NULLS   OFF    
  GO  
   
   
   
   
  ALTER           PROCEDURE   SOF_getmaxbh    
        @biaoshi   varchar(3), --单据类型标识  
        @addflag   integer, --0,1     在前台使用;2   组成一个号返回,序号不加1(结转号),3   序号加   1   返回(单据编号);  
        @maxbh   varchar(11)=NULL   output     --直接返回编号  
    AS  
     
    /***************************************************************/  
    --过程主题:获得单据编号       errorID=1800  
    /***************************************************************/  
     
    --内部变量声明  
    declare   @recnum   integer,  
                    @rowcount   integer  
    set   @recnum=0  
    /*非事务内容执行*/  
     
    --每一过程拥有一唯一区界号,过程内的异常编号在此基础上增加  
    declare   @errcode   integer  
    set   @errcode=1800                    
    declare   @return   integer  
    set   @return=0  
     
    --启动事务处理  
    declare   @tran_point   int --控制事务嵌套  
    set   @tran_point=@@trancount --保存事务点  
    if   @tran_point=0  
    begin   tran   tran_SOF_getmaxbh  
    else  
    save   tran   tran_SOF_getmaxbh  
     
    if   @addflag=1   or   @addflag=3  
    begin    
        update   maxbh     set   @recnum=recnum=recnum+1   where   biaoshi=@biaoshi  
        set   @rowcount=@@rowcount  
        if   @@error<>0  
        begin  
            set   @return=1  
            goto   err_lab  
        end    
    end  
    else  
    begin  
        select   @recnum=recnum   from   maxbh(nolock)   where   biaoshi=@biaoshi  
    end  
     
    if   @rowcount=0    
    begin  
        set   @recnum=0  
        insert   into   maxbh   (biaoshi,maxbh,mkbh,recnum)   values   (@biaoshi,'','',@recnum)  
    end  
     
    --返回结果  
    declare   @s_recnum   varchar(11)  
    set   @s_recnum=LTRIM(str(@recnum))  
     
    if   @addflag>1  
        set   @maxbh=@biaoshi+   REPLICATE('0',11-len(@biaoshi)-len(@s_recnum))+@s_recnum  
    else  
        select   @biaoshi+   REPLICATE('0',11-len(@biaoshi)-len(@s_recnum))+@s_recnum   as   recnum  
     
    --结束事务处理  
    if   @tran_point=0  
    commit   tran   tran_SOF_getmaxbh  
    goto   return_lab  
    err_lab:  
    if   @return<100   set   @return=@errcode   +@return  
    rollback   tran   tran_SOF_getmaxbh  
    return_lab:  
    return   @return    
   
   
   
   
  GO  
  SET   QUOTED_IDENTIFIER   OFF    
  GO  
  SET   ANSI_NULLS   ON    
  GO  
   
  问题点数:100、回复次数:7Top

1 楼gc_ding(施主,给个妞泡好么)回复于 2006-12-04 18:44:10 得分 0

帮项Top

2 楼zjcxc(邹建)回复于 2006-12-04 18:47:26 得分 100

--   应该让事务尽可能小,   包含最小的处理语句  
  --   楼主这个可以改成这样的  
   
  ALTER           PROCEDURE   SOF_getmaxbh    
        @biaoshi   varchar(3), --单据类型标识  
        @addflag   integer, --0,1     在前台使用;2   组成一个号返回,序号不加1(结转号),3   序号加   1   返回(单据编号);  
        @maxbh   varchar(11)=NULL   output     --直接返回编号  
    AS  
     
    /***************************************************************/  
    --过程主题:获得单据编号       errorID=1800  
    /***************************************************************/  
     
    --内部变量声明  
    declare   @recnum   integer,  
                    @rowcount   integer  
    set   @recnum=0  
    /*非事务内容执行*/  
     
    --每一过程拥有一唯一区界号,过程内的异常编号在此基础上增加  
    declare   @errcode   integer  
    set   @errcode=1800                    
    declare   @return   integer  
    set   @return=0  
     
  IF   @addflag=1   or   @addflag=3  
  BEGIN  
  --启动事务处理  
  declare   @tran_point   int --控制事务嵌套  
   
  set   @tran_point=@@trancount --保存事务点  
  if   @tran_point=0  
  begin   tran   tran_SOF_getmaxbh  
  else  
  save   tran   tran_SOF_getmaxbh  
   
  DECLARE   @err   int  
  update   maxbh     set   @recnum=recnum=recnum+1   where   biaoshi=@biaoshi  
  SELECT   @rowcount=@@rowcount,   @err   =   @@ERROR  
  if   @err<>0  
  begin  
  set   @return=1  
  goto   err_lab  
  end    
   
  if   @rowcount=0    
  begin  
  set   @recnum=0  
  insert   into   maxbh   (biaoshi,maxbh,mkbh,recnum)   values   (@biaoshi,'','',@recnum)  
  end  
  if   @@ERROR<>0  
  begin  
  set   @return=1  
  goto   err_lab  
  end    
   
    --结束事务处理  
  if   @tran_point=0  
  commit   tran   tran_SOF_getmaxbh  
  END  
  ELSE  
  begin  
        select   @recnum=recnum   from   maxbh(nolock)   where   biaoshi=@biaoshi  
  end  
   
    --返回结果  
    declare   @s_recnum   varchar(11)  
    set   @s_recnum=LTRIM(str(@recnum))  
     
    if   @addflag>1  
        set   @maxbh=@biaoshi+   REPLICATE('0',11-len(@biaoshi)-len(@s_recnum))+@s_recnum  
    else  
        select   @biaoshi+   REPLICATE('0',11-len(@biaoshi)-len(@s_recnum))+@s_recnum   as   recnum  
     
    --结束  
    goto   return_lab  
    err_lab:  
  if   @return<100   set   @return=@errcode   +@return  
  rollback   tran   tran_SOF_getmaxbh  
   
    return_lab:  
    return   @return    
  GOTop

3 楼zjcxc(邹建)回复于 2006-12-04 18:48:41 得分 0

试试上面调整之后和算法  
   
  另外,   楼主的处理语句中,   下面是有问题的  
        update   maxbh     set   @recnum=recnum=recnum+1   where   biaoshi=@biaoshi  
        set   @rowcount=@@rowcount  
        if   @@error<>0                 --   这里得到的是上面那个SET赋值是否有错误,   如果UPDATE出错,   则不会被捕获到  
        begin  
            set   @return=1  
            goto   err_lab  
        endTop

4 楼zjcxc(邹建)回复于 2006-12-04 18:49:48 得分 0

需要说明的是,   楼主的事务有可能是依赖于外部事务的,   这样分析起来就比较复杂了,   因为死锁不一定跟你帖出的这个过程有关,   有可能是外部的处理语句导致.Top

5 楼eason2000(eason)回复于 2006-12-05 09:02:29 得分 0

老大说的没错,我这个过程在很多业务里都要调用,来取得当前的单据序号。下面是我一调用的该过程的语句,您帮我看看?  
   
   
  Top

6 楼eason2000(eason)回复于 2006-12-05 09:06:46 得分 0

SET   QUOTED_IDENTIFIER   OFF    
  GO  
  SET   ANSI_NULLS   OFF    
  GO  
   
   
   
  --   进销单据存储  
     
    ALTER           procedure   SBP_jx_dj  
          @gzid   char(20),  
          @djlxbs   char(3)  
    as  
    /***************************************************************  
    过程主题:进销单据存储       errorID=900  
     
    2002-11-21   zxm   出库且结算登记   cwk   时单据号记录错误。  
    2002-12-04   zxm   机器号辅助录入应根据高级选项进行存盘。  
    2003-01-06   liush   增加换货管理,换货标志登记在cwk中。  
    2004-12-15   lixd   增加else语句,连接多个IF语句  
    2005-04-28   Victor   Ben   登记ywjsmx前,计算yisfje错误,退回单增加(@isth<>-1)判断  
    ***************************************************************/  
    --每一过程拥有一唯一区界号,过程内的异常编号在此基础上增加  
    declare   @errcode   integer  
    set   @errcode=900                 /*   进销单据存储*/                      
     
     
    declare   @return   integer /*返回结果的初始化*/  
    set   @return=0  
     
     
    declare    
        @djbh char(14),  
        @jsdjlx   char(3),  
        @jsdjbh   char(14),  
        @jxlx   char(1),  
        @djlx   char(3),  
        @rq   char(10),  
        @dwbh   char(11),  
        @bm   char(20),  
        @ywy   char(20),  
        @username   char(20),  
        @jzhh   char(11),  
        @zhy   char(30),  
        @isjs   char(2),  
        @jsfsid   char(11),  
        @jiesje   dec(14,2),  
        @zhph   char(12),  
        @cor_ysh   dec(20,2),  
        @cor_yf   dec(20,2),  
        @tmp_zoo   dec(14,2),  
        @lastsj   char(2), --最后售价管理  
        @mu_dingd   char(2), --允许订单多次执行  
        @chonghong   char(2), --冲红  
        @ck_auto_ph   char(2), --出库自动分摊批号  
        @autoph   int, --自动分摊批号  
        @djmxfzjqh   char(2), --机器号辅助录入  
        @m   int,  
        @isth   int, --退货  
        @istbj   int, --退补价  
        @is_hh   char(2),  
        @bendian   char(3)  
     
     
     
        set   @zhph=''  
        set   @djbh=''  
        set   @bm=''  
        set   @ywy=''  
        set   @zhy=''  
        set   @rq=''  
        set   @isjs='否'  
        set   @jsfsid=''  
        set   @jiesje=0  
        set   @cor_ysh=0  
        set   @cor_yf=0  
        set   @tmp_zoo=0  
        set   @m=0  
        set   @isth=1  
        set   @istbj=1  
        set   @lastsj='否'  
        set   @chonghong='否'  
        set   @mu_dingd='否'  
        set   @ck_auto_ph='否'  
        set   @autoph=0  
        set   @djmxfzjqh='否'         --机器号辅助录入  
        set   @is_hh='否'  
        set   @bendian=''  
     
    --增加一临时缓存  
     
        select   @djbh=case   fieldname   when   'djbh'   then   left(fieldvalue,14)   else   @djbh   end,  
                      @dwbh=case   fieldname   when   'dwbh'   then   left(fieldvalue,11)   else   @dwbh   end,  
                      @bm=case   fieldname   when   'bm'then   left(fieldvalue,20)   else   @bm   end,  
                      @ywy=case   fieldname   when   'ywy'then   left(fieldvalue,20)   else   @ywy   end,  
                      @username=case   fieldname   when   'username'then   left(fieldvalue,20)   else   @username   end,  
                      @zhy=case   fieldname   when   'zhy'then   left(fieldvalue,30)   else   @zhy   end,  
                      @rq=case   fieldname   when   'rq'   then   left(fieldvalue,10)   else   @rq   end,  
                      @isjs=case   fieldname   when   'isjs'then   left(fieldvalue,2)   else   @isjs   end,  
                      @jsfsid=case   fieldname   when   'jsfsid'then   left(fieldvalue,11)   else   @jsfsid   end,  
                      @zhph=case   fieldname   when   'zhph'then   left(fieldvalue,12)   else   @zhph   end,  
                      @mu_dingd=case   fieldname   when   'MU_DINGD'then   left(fieldvalue,2)   else   @mu_dingd   end,  
                      @chonghong=case   fieldname   when   'dj_chonghong'then   left(fieldvalue,2)   else   @chonghong   end,  
                      @ck_auto_ph=case   fieldname   when   'ck_auto_ph'then   left(fieldvalue,2)   else   @ck_auto_ph   end,  
                      @djmxfzjqh=case   fieldname   when   'DJMXFZ'then   left(fieldvalue,2)   else   @djmxfzjqh   end,  
                      @lastsj=case   fieldname   when   'ZHSHJ'then   left(fieldvalue,2)   else   @lastsj   end,  
                      @bendian=case   fieldname   when   'bendian'   then   left(fieldvalue,3)   else   @bendian   end,  
                      @jiesje=case   fieldname   when   'sjsz'   then   round(convert(decimal(14,2),rtrim(fieldvalue)),2)   else   @jiesje   end,  
                      @is_hh=case   fieldname   when   'is_hh'   then   left(fieldvalue,2)   else   @is_hh   end  
        from       tmp_dj_mast   (nolock)  
        where     gzid=@gzid   and   fieldname   in   ('djbh','dwbh','bm','ywy','username','zhy','rq','isjs','jsfsid','zhph','sjsz','ZHSHJ','MU_DINGD','dj_chonghong','ck_auto_ph','DJMXFZ','is_hh','bendian')  
     
         
    set   @jxlx=left(@djbh,1)  
    set   @djlx=left(@djbh,3)  
     
     
    --select   @istbj=case   @djlx   when   'JHB'   then   0   when   'XSB'   then   0   end,@isth=case   @djlx   when   'JHC'   then   -1   when   'XSC'   then   -1   end,@isjs=case   @isjs   when   ''   then     '否'   end  
     
    if   @djlx='JHB'   or   @djlx='XSB'    
    begin  
    set   @istbj=0  
    end  
   
    if   @djlx='JHC'   or   @djlx='XSC'    
    begin  
    set   @isth=-1  
    end  
         
    if   @isjs=''    
    begin  
          set   @isjs='否'  
    end  
     
    if   @djlx='XSA'  
    begin  
    if   @ck_auto_ph='是'    
          set     @autoph=1  
    end  
     
    exec   @return=SOF_getmaxbh   'JZH',2,@jzhh   OUTPUT  
   
        if   @return>0    
            goto   err_lab  
     
    --启动事务处理  
    declare   @tran_point   int --控制事务嵌套  
    set   @tran_point=@@trancount --保存事务点  
    if   @tran_point=0  
    begin   tran   tran_jxdj  
    else  
    save   tran   tran_jxdj  
     
     
    --创建临时结构  
     
    create   table   #t_djmx   (  
        djbh   char(14)   null   default   '',  
        rq   char(10)   null   default   '',  
        dwbh   char(11)   null   default   '',  
        bm   char(20)   null   default   '',  
        ywy   char(20)   null   default   '',  
        username   char(20)   null   default   '',  
        zhy   char(30)   null   default   '',  
        spid   char(11)   null   default   '',  
        xgdjbh   char(14)   null   default   '',  
        isjs   char(2)   null   default   '否',  
        hw   char(11)   null   default   '',  
        pihao   char(20)   null   default   '',  
        pici   char(20)   null   default   '',  
        baozhiqi   char(10)   null   default   '',  
        miejph   char(12)   null   default   '',  
        sxrq   char(10)   null   default   '',  
        dj_sn   integer   null   default   0,  
        dj_sort   integer   null   default   0,  
        recnum   integer   null   default   0,  
        shl   decimal(14,2)   null   default   0,  
        dj   decimal(16,6)   null   default   0,  
        je   decimal(14,2)   null   default   0,  
        shlv   decimal(14,2)   null   default   0,  
        hshj   decimal(16,6)   null   default   0,  
        hsje   decimal(14,2)   null   default   0,  
        she   decimal(14,2)   null   default   0,  
        lshje   decimal(14,2)   null   default   0,  
        ml   decimal(14,2)   null   default   0,  
        plcj   decimal(14,2)   null   default   0,  
        lshj   decimal(14,2)   null   default   0,  
        buckcb   decimal(14,2)   null   default   0,  
        bukccb   decimal(14,2)   null   default   0,  
        canssl   decimal(14,2)   null   default   0,  
        quxsl   decimal(14,2)   null   default   0,  
        duiydjbh   char(14)   null   default   '',  
        duiydj_cn   int   null   default   0  
    )Top

7 楼caixia615(*^_^*)‵My ɡīr!.ˊ想念妳ˋ 。(*^_^*)回复于 2006-12-05 09:15:02 得分 0

mark,学习Top

相关问题

关键词

得分解答快速导航

  • 帖主:eason2000
  • zjcxc

相关链接

  • SQL Server类图书

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo