现在有这样一个项目,定时向5个数据库的表里面取数据到另外一个数据库A里面。
而这5个数据库里面的表并不是同时向A这个数据库里面送数据,有些是每隔30分钟
的,有些是每隔20分钟的,有些是每隔一个小时的,有些是每隔一天的。
我现在的设计思路是建一个表,里面存放目标表和源表,以及起始传送时间,
截止传送时间,时间间隔。然后用TIMER每隔一秒就扫描这个表一次,找出那个
时候要传数据的源表和目标表,然后传送数据到目标服务器。代码如下。
但是我遇到以下几个问题:
1,容错问题。我想实现就是当扫描存放目标表和源表的表的时候,如果源表已经不存在(程序会报错)
了这个时候就要跳过这条记录,到下一条在执行,但在我的程序里面我用了TRY ,EXCEPT,可是到了
源表或目标表不存在这种情况的时候,会有错误提示,但是不跳过去继续执行下一条。而且TIMER还
没有停止。
2,效率问题。假如我正在执行一个每1个小时传送一次数据的时候,数据比较多,要传送25分钟,但当
我传送数据的时候,我发现TIMER没有动了,因为在执行传数据。假如已经传送了20分钟,这个时候
有一个每隔20分钟要传送一次数据的记录要运行,但是,它执行的时间是和TIMER比的,所以它不能够
及时的执行,这类问题在我这个项目里面很普遍,我没有什么好的办法,希望高手能够给些好的建立和
解决办法。procedure TForm1.Timer1Timer(Sender: TObject);
var tpstr,tpstra:string;
    times :integer ;
    sser,dser,sdb,ddb,stb,dtb,succ,ops,opdate :string;
    sstr ,dstr ,bdstr,sdate,sdateb,zqdm ,updtime:string;
    i,j,inc:integer ;
begin
  label15.Caption :=datetimetostr(now);
  tpstr :=datetimetostr(now);
  with ut_dm.DataModule2 do
  begin
    sqy.Active :=false 
    sqy.SQL.Clear ;
    sqy.SQL.Add('update traninf set succ='+#39+'NO'+#39);
    sqy.ExecSQL ;
    Sqy.Close ;
    Sqy.SQL.Clear ;
    Sqy.SQL.Add('select * from traninf where optdate='+#39+tpstr+#39);
    Sqy.Open ;
    Sqy.First ;
    if not Sqy.eof then
    begin
      while not Sqy.Eof do
      begin
        stb :=Sqy.Fields[2].AsString ;
        dtb :=Sqy.Fields[5].AsString ;
        sdateb :=sqy.Fields[7].Value ;
        inc :=sqy.Fields[11].Value ;
        sdate:=copy(tpstr,1,4)+copy(tpstr,6,2)+copy(tpstr,8,2);
        begin
          try
          try
            ddataqy.Active :=false ;
            ddataqy.SQL.Clear ;
            ddataqy.SQL.Add('delete from '+dtb);
            ddataqy.ExecSQL ;
            ddataqy.Active :=false ;
            ddataqy.SQL.Clear ;
            ddataqy.SQL.Add('select * from '+dtb);
            sdataqy.Active :=false ;
            sdataqy.SQL.Clear ;
            sdataqy.SQL.Add(' select * from '+stb);
            sdataqy.Active :=true ;
            ddataqy.Active :=true ;
            sdataqy.First ;
            while not sdataqy.eof do
            begin
              try
                ddataqy.Append ;
                for i:=0 to sdataqy.FieldCount-1 do
                begin
                  ddataqy.Fields[i].Value :=sdataqy.Fields[i].Value ;
                end;
                ddataqy.Post ;
              except
                ddataqy.Cancel ;
              end;
              sdataqy.Next ;
            end;
          except
            sdataqy.Active :=false ;
            ddataqy.Active :=false ;
            sqy.Edit ;
            sqy.FieldByName('succ').AsString :='NO' ;
            sqy.FieldByName('optdate').Value :=IncMinute(strtodatetime(sdateb),inc) ;
            sqy.FieldByName('counts').AsInteger :=sqy.fieldbyname('counts').AsInteger+1;
            sqy.Post ;
            sqy.Next ;
          end;
          finally
            sqy.Edit ;
            sqy.FieldByName('succ').AsString :='OK' ;
            sqy.FieldByName('optdate').Value :=IncMinute(strtodatetime(sdateb),inc) ;
            sqy.FieldByName('counts').AsInteger :=sqy.fieldbyname('counts').AsInteger+1;
            sqy.Post ;
            sqy.Next ;
          end;
        end;
      end;
    

解决方案 »

  1.   

    我的想法:  1.先将每种向A数据库中填写数据的存储过程(或类)写好。
      2.将传输条件(时间,源表,目标表)等信息写到一个配置文件中,最好是用XML文件定义。
      3.写一个执行类先将配置读入,给每一个传输条件开一个线程,根据时间的不同来定时执行。不过要注意的是,如果有一个条件是每一分钟传送一次,而每一次执行的时间要大于一分钟就会有问题,解决的方法是你好好分析一下你的业务,如确实无法避免这种情况则只有给每一次传输都单独开一线程,不知你用什么数据库??我想是这样解决,你要根椐业务要求来仔细分析。
      

  2.   

    呵呵,我有个异地数据同步的方案,也是使用了类似的方法,不过没有你的这么复杂
    1,容错问题。我想实现就是当扫描存放目标表和源表的表的时候,如果源表已经不存在(程序会报错)
    了这个时候就要跳过这条记录,到下一条在执行,但在我的程序里面我用了TRY ,EXCEPT,可是到了
    源表或目标表不存在这种情况的时候,会有错误提示,但是不跳过去继续执行下一条。而且TIMER还
    没有停止。
    建议:改用判断原表是否存在的方法,(有点奇怪,原表怎么会不在了),
    不要用TRY,EXCEPT的方法,如果用的是MSSQL,就用
    if   e x i s t s   ( s e l e c t   *   f r o m   d b o . s y s o b j e c t s   w h e r e   i d   =   o b j e c t _ i d ( N ' [ d b o ] . [ your tablename] ' ) 2,效率问题。假如我正在执行一个每1个小时传送一次数据的时候,数据比较多,要传送25分钟,但当我传送数据的时候,我发现TIMER没有动了,因为在执行传数据。假如已经传送了20分钟,这个时候有一个每隔20分钟要传送一次数据的记录要运行,但是,它执行的时间是和TIMER比的,所以它不能够及时的执行,这类问题在我这个项目里面很普遍,我没有什么好的办法,希望高手能够给些好的建立和解决办法。
    在传送数据是,采用TIME来激发一个传送线程,这样你的TIMER就不会出现这样的问题了;
      

  3.   

    那么如何在TIMER里面开辟多线程呢?