我在CSDN搜索了一下,关于这个问题已经有N多人提过了。我收集了一些解决的资料:  
1.  EXEC  sp_configure  'locks',  '0'    
2.  SET  TRANSACTION  ISOLATION  LEVEL  READ  UNCOMMITTED  //脏读  
3.  begin  tran  
     select  new_id  from  keytab  holdlock  
     update  keytab  set  new_id=new_id+1  
     commit  tran  
4    SET  Lock_TimeOut  2000  
 
在这些语句都能通过,特别是以脏读的方式,我在客户的数据库中执行后,他们的数据库还是会出现在死锁现象,并将当前进程作为牺牲品。它是在程序中执行的sql语句(insert,update,select,insert占多数),CSDN哥哥们说应该写在存储过程中,避免写在程序中,照我现在的情况来看,如果修改程序,将整个企业生产部的所有都要更换,有没有另外的办法?  
设置脏读是不是只需要执行一次即可解决?  
 
--------------------------------------------------------------------------------------------------------我此段程序操作  数据表不多,只有两个,但insert记录很频繁,  
有一个是公共的表m_publicpart,它是master表  
另个一外是部门生产明细表m_partX.  "X  "可为1,2,3,4......  
意思是说生产一部为m_part1,  生产二部为m_part2.......  
 
我想不应该是数据表顺序的问题吧,该如何跟踪啊?请哥哥们指教啊。 -------------------------------------------------------------------------------------------------------增加TempDB的数据文件大小和日志文件大小能行吗? ----------------------------------------------------------------------------------------------------------后来把这段程序中所有的insert,update,select都加了with(updlock)
如:select * from table1 with(updlock) where ....
也没有解决问题。
---------------------------------------------------------------------------------------------------------
如果是杀进程,该怎么写啊,写为一个触发器好呢,还是写成过程?恳求哥哥们解答
--------------------------------------------------------------------
 每个控件在做事件的时候都先
 if qrlcdnrb.active then qrlcdnrb.close;
 是先释放了资源后再做的事啊。

解决方案 »

  1.   

    少量死锁的发生是正常的,因为软件毕竟比较复杂,有时候没有调整好,就比较容易发生
    死锁频繁的话,可以先看看那些操作容易发生死锁,然后分析一下他们做了什么
    比如某一个操作,先读数据A,然后写数据B,而另一个操作先读数据B,然后写数据A,当A和B的读都需要比较长的时间,那么出现死锁的概率就很高了,但是有时候我们的业务的的确确是这样的,那么你可以让这些操作排队,简单的方法是:设立一个锁表,专门用于控制锁(用户方式),重新安排前面的两个操作,让他们首先独占锁定这个锁表,然后再执行他们的操作,(我不是很了解sql server,不过好像记得有个显式锁定表的函数或者事务参数,)
    这样:
    OPERATION1:
       LOCK(T_LOCK);
       READ(A);
       WRITE(B);OPERATION2:
      

  2.   

    OPERATION2:
       LOCK(T_LOCK);
       READ(B);
       WRITE(A);
      

  3.   

    我把保存数据的这段代码贴出来,大家帮我看一下。非常感谢。看重点哈要不然头闷!!procedure Tfmlcdsr1.Button5Click(Sender: TObject);
    //把流程单内容写入流程单内容表,更新流程单输入登记表和流程单反馈登记表
    const
       lcddjsql:string='select * from cj_lcdsrdjb';
    var
       lcdh,sfhsg,cplb:string;
       i,j:integer;
       trs,hga,hgb,hgc,ccs,hgs,bhgs,zs,hj,zr,fk,ccfk:integer;
       lastProcedure:string;
       lastProcedureFk,lastProcedureZps: integer;
       qsgx,jsgx:string;
       firstGxFlag:boolean;   //承接流程单相关信息
       cjbmbh,cjid,cjlcdh,cjph,cjcplbh:string;   insertLcdnrbValues:string;
       insertLcdnrbValuesCount : integer;
       insertLcdnrbFirstValue : string;
       insertLcdnrbFirstValueIndex : integer;
       tmp:string;   lcdsrdjbfk:integer;
    begin
       if (edlcdh1.Text='') or (edlcdh2.text='') then
       begin
          showmessage('流程单号未填写');
          exit;
       end
       else
       if edph.text='' then begin
          showmessage('批号未填写');
          exit;
       end
       else
       if lkcplb.keyvalue=null then begin
          showmessage('产品类别未选择');
          exit;
       end
       else
       if edzp.Text='' then begin
          showmessage('流程单的折片数是指本张流程单最后一道工序所加工出的产品的折片系数,不能为空!');
          edzp.text := '1';
          exit;
       end
       else
       if edtrs.text='' then
       begin
           showmessage('投入数不能为空!');
           exit;
       end
       else
       begin
          lcdh:=edlcdh1.text+edlcdh2.text;
          if dmcjgl.qrlcdsrdjb.Active then dmcjgl.qrlcdsrdjb.close;
          dmcjgl.qrlcdsrdjb.SQL.clear;
          dmcjgl.qrlcdsrdjb.SQL.append('select lcdh from cj_lcdsrdjb with(updlock) where lcdh='''+lcdh+'''');
          dmcjgl.qrlcdsrdjb.open;
          dmcjgl.qrlcdsrdjb.first;
          if not dmcjgl.qrlcdsrdjb.eof then
          begin
             showmessage('此流程单号已存在,不能输入');
             dmcjgl.qrlcdsrdjb.close;
             exit;
          end
          else
          //如果有承接流程单则要检验承接流程单是否输入并存在
          if edcjlcdh1.Visible then
          begin
               if (edcjlcdh1.text='')or(edcjlcdh2.text='') then
               begin
                  showmessage('承接流程单号未填写');
                  exit;
               end
               else
               begin
                  if dmcjgl.qrlcdsrdjb.Active then dmcjgl.qrlcdsrdjb.close;
                  cjlcdh:=edcjlcdh1.text+edcjlcdh2.text;
                  dmcjgl.qrlcdsrdjb.SQL.clear;
                  dmcjgl.qrlcdsrdjb.SQL.append('select * from cj_lcdsrdjb with(updlock) where lcdh='''+cjlcdh+'''');
                  dmcjgl.qrlcdsrdjb.open;
                  dmcjgl.qrlcdsrdjb.first;
                  if dmcjgl.qrlcdsrdjb.eof then
                  begin
                     showmessage('此承接流程单号不存在,不能输入');
                     dmcjgl.qrlcdsrdjb.close;
                     exit;
                  end;
                  cjbmbh := dmcjgl.qrlcdsrdjb.fieldbyname('bmbh').asstring;
                  cjid := dmcjgl.qrlcdsrdjb.fieldbyname('id').asstring;
                  cjph := dmcjgl.qrlcdsrdjb.fieldbyname('ph').asstring;
                  cjcplbh := dmcjgl.qrlcdsrdjb.fieldbyname('cplbh').asstring;
               end;
          end;
      

  4.   

    承接上:
    {以下是逻辑错误
          //如果没有承接流程单,投入数即为投入数×投入折片数
          else
          begin
              parttrs := strtoint(edtrs.text)*strtoint(edtrzp.text);
          end;
          }
          //更新投入数
          parttrs := strtoint(edtrs.text)*strtoint(edtrzp.text);
          if dmcjgl.qrlcdsrdjb.Active then dmcjgl.qrlcdsrdjb.close;      //检验用户输入的流程单内容是否合法
          if not checkvalid then
          begin
              exit;
          end
          //处理用户流程单内容的输入数据
          {数据项单位说明:合成工序的的所有数据项的计量单位均为片,用户输入数据的大小由用户自己换算确定,
          其他工序所有数据按指定工序所加工的物品的实物形态为单位}
          else
          with dmcjgl do
          begin
            dmerp.dberp.starttransaction;
            try
            begin
                trs := parttrs;            hga := 0;
                hgb := 0;
                hgc := 0;
                hgs := 0;            zs := 0;
                zr := 0;
                fk := 0;
                bhgs := 0;            ccs := 0;            cplb:=string(lkcplb.keyvalue);            firstGxFlag := true;            //登记流程单内容数据到相应的部门流程单数据表中
                if qrlcdnrb.active then qrlcdnrb.close;
                qrlcdnrb.SQL.clear;            for i:=1 to stringgrid1.RowCount-1 do
                begin
                    if stringgrid1.Cells[2,i]<>'' then
                    begin
                           qrlcdnrb.SQL.append(format('insert cj_lcdnrb'+dlbmbh+' WITH (updlock) (bmbh,id,lcdh,gxdm,gh,trs,ccs,zs,hj,zr,fk,cplbh,hga,hgb,hgc,tag,cczpxs) values(''%s'',''%s'',''%s'',%s,''%s'',%s,%s,%s,%s,%s,%s,''%s'',%s,%s,%s,''%s'',%s)',
                                     [dlbmbh,dlbmid,lcdh,stringgrid1.cells[0,i],stringgrid1.cells[2,i],stringgrid1.cells[11,i],stringgrid1.cells[3,i],
                                     stringgrid1.cells[7,i],stringgrid1.cells[8,i],stringgrid1.cells[9,i],stringgrid1.cells[10,i],
                                     cplb,stringgrid1.cells[4,i],stringgrid1.cells[5,i],stringgrid1.cells[6,i],qrcplb.fieldbyname('tag').asstring,stringgrid1.cells[12,i]]));                       //如果包含附加工序,则增加这张流程单的投入数
                           if firstfjindex[i-1] = '1' then
                           begin
                               trs := trs + strtoint(stringgrid1.cells[11,i])*strtoint(stringgrid1.cells[12,i]);
                           end;                       hga := strtoint(stringgrid1.cells[4,i])*strtoint(stringgrid1.cells[12,i]);
                           hgb := strtoint(stringgrid1.cells[5,i])*strtoint(stringgrid1.cells[12,i]);
                           hgc := strtoint(stringgrid1.cells[6,i])*strtoint(stringgrid1.cells[12,i]);                       hgs:= hga+hgb+hgc;                       zs := zs + strtoint(stringgrid1.cells[7,i])*strtoint(stringgrid1.cells[12,i]);
                           zr := zr + strtoint(stringgrid1.cells[9,i])*strtoint(stringgrid1.cells[12,i]);
                           fk := fk + strtoint(stringgrid1.cells[10,i])*strtoint(stringgrid1.cells[12,i]);                       bhgs := zs +zr + fk;
                           ccs:= strtoint(stringgrid1.cells[3,i])*strtoint(stringgrid1.cells[12,i]);                       //登记本张流程单的起始和结束工序
                           if firstGxFlag then
                           begin
                               qsgx := stringgrid1.cells[0,i];
                               firstGxFlag := false;
                           end;
                           jsgx := stringgrid1.cells[0,i];                       lastProcedure := stringgrid1.cells[0,i];                       lastProcedureZps := strtoint(stringgrid1.cells[12,i]);
                    end;
                end;
      

  5.   

    承接上:
                //登记流程单登记表            if qrlcdnrb.SQL.Count>0 then
                begin
                    qrlcdnrb.execsql;
                    if qrlcdsrdjb.active then qrlcdsrdjb.close;
                    qrlcdsrdjb.sql.clear;
                    if rghsg.Checked then sfhsg:='1' else sfhsg:='0';
                    qrlcdsrdjb.sql.append('insert cj_lcdsrdjb WITH (updlock) (bmbh,id,lcdh,ph,cplbh,dylcdh,trs,ccs,cchgs,hgl,ifout,ifkucun,ljbhgs,lz,sw,sfhsg,gl,zp,cpmc,qsgx,jsgx) '+format('values(''%s'',''%s'',''%s'',''%s'',''%s'',''%s'',%s,%s,%s,round(%s,4),''%s'',''%s'',%s,''%s'',''%s'',''%s'',''%s'',%f,''%s'',''%s'',''%s'')',
                             [dlbmbh,dlbmid,lcdh,edph.text,cplb,cjlcdh,inttostr(trs),inttostr(ccs),inttostr(hgs),
                              floattostr(hgs/trs),'否','否',inttostr(bhgs),stlz.caption,stsw.caption,sfhsg,stgl.caption,strtofloat(edzp.text),lkcplb.text,qsgx,jsgx]));
                    qrlcdsrdjb.execsql;
                    if qrlcdnrb.Active then qrlcdnrb.close;
                    if qrlcdsrdjb.Active then qrlcdsrdjb.Close;
                end
                else
                begin
                    showmessage('流程单中无工序记录!');
                    if qrlcdnrb.Active then qrlcdnrb.close;
                    clearform;
                    exit;
                end;            //登记反馈信息
                if edcjlcdh1.Visible then
                begin
                    if qrlcdnrb.active then qrlcdnrb.close;
                    qrlcdnrb.sql.clear;
                    fk:=0;
                    lcdsrdjbfk := 0;
                    lastProcedureFk := 0;
                    for j:=1 to stringgrid2.RowCount-1 do
                    begin
                        if (stringgrid2.Cells[3,j]<>'')and(stringgrid2.Cells[4,j]<>'') then
                        begin
                            qrlcdnrb.sql.append(format('update cj_lcdnrb'+cjbmbh+' WITH (updlock) set fk=fk+%s,HGA=HGA-%S where BMBH = ''%S'' and ID = ''%S'' and  LCDH=''%S'' and CPLBH = ''%S'' AND gxdm=''%s''',
                                      [stringgrid2.Cells[4,j],stringgrid2.Cells[4,j],cjbmbh,cjid,cjlcdh,cjcplbh,stringgrid2.Cells[0,j]]));
                            fk:=fk+strtoint(stringgrid2.Cells[4,j]);
                            lcdsrdjbfk := lcdsrdjbfk + strtoint(stringgrid2.Cells[4,j])*strtoint(stringgrid2.Cells[2,j])
                        end;
                    end;
                    if (qrlcdnrb.sql.Count>0) then
                    begin
                        qrlcdnrb.execsql;
                        if qrlcdsrdjb.active then qrlcdsrdjb.close;
                        qrlcdsrdjb.sql.clear;
                        qrlcdsrdjb.sql.append(format('update cj_lcdsrdjb WITH (updlock) set CCHGS=CCHGS-%d,LJBHGS=LJBHGS+%d,HGL = CCHGS/cast(TRS as float(24)) where bmbh = ''%s'' and id = ''%s'' and lcdh=''%s'' and ph = ''%s'' and cplbh = ''%s''',
                                       [lcdsrdjbfk,lcdsrdjbfk,cjbmbh,cjid,cjlcdh,cjph,cjcplbh]));
                        qrlcdsrdjb.execsql;
                    end;
                    if qrlcdnrb.Active then qrlcdnrb.close;
                    if qrlcdsrdjb.active then qrlcdsrdjb.close;
                end;            //登记反馈内容
                if qrfk.Active then qrfk.Close;
                qrfk.sql.clear;
                if (edcjlcdh1.visible) and (edcjlcdh1.text <>'') then
                begin
                    for i:=1 to stringgrid2.rowcount-1 do
                    begin
                        if (stringgrid2.Cells[3,i]<>'')and(stringgrid2.Cells[4,i]<>'') then
                        begin
                            if qrtmp.Active then qrtmp.close;
                            qrtmp.sql.clear;
                            qrtmp.sql.append('select * from cj_lcdfkdjb WITH (updlock) where lcdh='''+cjlcdh+
                                           ''' and fklcdh='''+lcdh+''' AND gxdm='+stringgrid2.cells[0,i]);
                            qrtmp.open;
                            if qrtmp.RecordCount>0 then
                             qrfk.sql.append('update cj_lcdfkdjb WITH (updlock) set fks=fks+'+stringgrid2.cells[4,i]+
                                             ' where lcdh='''+cjlcdh+''' and fklcdh='''+lcdh+
                                             ''' and gxdm='+stringgrid2.cells[0,i])
                            else
                             qrfk.sql.append('insert into cj_lcdfkdjb WITH (updlock) values('''+cjlcdh+''','+
                                             stringgrid2.cells[0,i]+','+stringgrid2.cells[4,i]+','''+lcdh+''')');
                            qrtmp.close;
                        end;
                    end;
                    if qrfk.sql.count>0 then qrfk.execsql;
                    if qrfk.Active then qrfk.Close;
                end;            dmerp.dberp.commit;
                clearform;
            end
            except
                dmerp.dberp.rollback;
                dealBuffer;
                raise;
            end;
          end;
       end;
       gobackflag := false;
    end;