在一个数据添加界面
我开始了一个数据库事务,代码写在新增按钮的单击事件中,代码如下
  if d_dateml.ADOConn.InTransaction then
    d_dateml.ADOConn.CommitTrans ;
  //开始数据库事务,数据回滚
  d_dateml.ADOConn.BeginTrans ;
  //添加客户消费
  with sales_dateset do
    begin
      append;
      fieldbyname('MembershipCop').AsString :=u_loginland.SOfficeName ;
      fieldbyname('Date_time').AsDateTime:=strtodatetime(formatdatetime('YYYY-MM-DD',date));
      fieldbyname('serial_no').AsString :=serialno(d_dateml.itemno_query,'sales');//自定义函数
      fieldbyname('money').AsFloat :=0.00 ;
    end;
自定义函数说明如下
function serialno(adoquery:tadoquery;itemname:string):string;  //系统自动编号用在新增按钮中
var
  bm,maxbm:string; //系统自动编号
begin
  //系统自动编号
  with adoquery do
    begin
      SQL.Text:='select * from item_no where itemname='''+itemname+''' and membershipcop='''+SOfficeName+'''';
      close;
      open;
      if recordcount<>0 then
        begin
          while fieldbyname('lockflag').AsBoolean do
            begin
              requery();//刷新等待
            end;
          edit;
          fieldbyname('lockflag').AsBoolean:=true;//人工加锁
          post;
          //月份不同时,编号从1开始,否则加1
          if leftstr(fieldbyname('number').AsString,6)=formatdatetime('YYYYMM',now) then
            begin
              edit;
              result:=trim(fieldbyname('number').asstring);
              bm:=rightstr('00000'+inttostr(strtoint(rightstr(fieldbyname('number').AsString,5))+1),5);
              fieldbyname('number').AsString :=leftstr(fieldbyname('number').AsString,6)+bm;
              fieldbyname('lockflag').AsBoolean:=false;
              post;
            end
          else
            begin
              edit;
              fieldbyname('number').AsString :=formatdatetime('YYYYMM',now)+'00001';
              result:=formatdatetime('YYYYMM',now)+'00001';
              fieldbyname('lockflag').AsBoolean:=false;
              post;
            end;
        end
      else
        begin
          insert;
          fieldbyname('itemname').AsString :=itemname;
          fieldbyname('number').asstring:=formatdatetime('YYYYMM',now)+'00001';
          fieldbyname('membershipcop').AsString :=SOfficeName ;
          fieldbyname('lockflag').AsBoolean:=false;
          post;
          result:=formatdatetime('YYYYMM',now)+'00001';
        end;
      close;
    end;
end;
item_no 这个表用来存放系统需要自动编号的记录编号,表的结构如下:
itemname(项目名),number(编号),membershipcop(公司),lockflag(人工加锁标志)
我的问题是如果两个客户端同时点击新增按钮的话
其中一个客户端会奇慢无比,为什么?
高人给点意见或指教!!!!

解决方案 »

  1.   

    在你的处理方式之下,当数据库开始了一个事务,事务外查询是不被允许的(就是说必须等事务执行完了,才允许执行该事务之外的查询),因此你取最大编号的那个While循环是不起作用的(或者问题就出在那里)。
    你可以用简单的程序测试一下我所说的问题:
      with ADOConnection1 do
      begin
        BeginTrans;
        Execute('insert into t_test(content) values(''aa'')');  //随便往哪个表插入数据
        CommitTrans;   //在这里设置一个断点
      end;
    当程序执行到断点那里的时候,用查询分析器查询你正在操作的那个表,你可以发现这时候数据库是不会响应你的查询的,只有当CommitTrans或者RollbackTrans之后才会响应。
      

  2.   

    TO : hthunter(核桃) 
    function bm(adoquery:tadoquery):string;
    begin
      with adoquery do
        begin
          sql.text:='select * from bm'
          close;
          open;
          if recordcount<>0 then
            begin
              while fieldbyname('flag').AsBoolean do
                begin
                  Requery();
                end;
              edit;
              fieldbyname('flag').AsBoolean :=true;
              post;
              edit;
              result:= inttostr(fieldbyname('bm').AsInteger+1) ;
              fieldbyname('bm').AsInteger  :=fieldbyname('bm').AsInteger+1;
              fieldbyname('flag').AsBoolean :=false;
              post;
            end
          else
            begin
              insert;
              fieldbyname('bm').AsInteger :=1;
              fieldbyname('flag').AsBoolean :=false;
              post;
              result:='1' ;
            end;
        end;
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
      ADOConnection1.BeginTrans;
      with ADOQuery2 do
        begin
          insert;
          fieldbyname('bm').AsString :=bm(ADOQuery1);
          fieldbyname('qt').AsString:='123';
          post;
        end;
      ADOConnection1.CommitTrans;
    end;
    这段代码为什么就可以呢?
    再说我并没有操作开始事务的那个表。
    在给我说说!我不明白为什么?谢谢
      

  3.   

    高手!!!
    谢谢!
    还有到下面地址结分
    http://expert.csdn.net/Expert/topic/2479/2479224.xml?temp=.3592035