小弟对于多线程的操作不是太了解,通过看书知道可以用BDE的SESSION控件对数据库进行多线程操作,尝试改成用ADO对程序改进,却发现ADO的控件不能和SESSION配合使用。请问各位大虾们有没有通过ADO对数据库多线程进行操作的示例啊??

解决方案 »

  1.   

    ADO不需要使用Session的,ADO在线程内使用要加  CoInitialize(nil);
      

  2.   

    楼主没有搞清程序在系统中到底是如何执行的.CPU只是在执行线程,对于CPU来说没有主线程,子线程之分.
    当你启动一个程序的时候就自动建立了一个线程,你的程序不运行多线程的时候你的ADO也是在一个线程中执行的.多线程就象是原来DOC下的内存一样,所有的程序都是可以访问的.现在当你在一个程序中创建多个线程的时候,这个程序所有的资源就会让多个线程共享,也就是会发生资源访问冲突.当前在多个线程中访问一个ADOQuery 时就会造成冲突,其中一个线程让它执行一个SQL语句还没有结束的时候,另一个线程就可能也让它执行一个SQL语句,就会出错,所以在多线程的时候我们要做好叉道工的工作,不能让各个线程同时走上一条铁路线,也不能认为一个在前面执行,另一个在后面执行就不会出错.所以多线程重要的是搞清它们可能会共同访问什么资源,然后用一些系统提供的方式避免错误.如果有一个全局变量I:integer; i:=1 两个程序都时执行 i:=i+1;这样的操作都有可能值是错误的,两个线程都执行后值还是1;有本书叫<Windows核心编程>里面讲的清楚。
      

  3.   

    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, DB, ADODB;const
      WellNo = 5;type
      TForm1 = class(TForm)
        ADODataSet1: TADODataSet;
        ADODataSet2: TADODataSet;
        ADODataSet3: TADODataSet;
        ADODataSet4: TADODataSet;
        ADODataSet5: TADODataSet;
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;type TThdReadWData= class( TThread )
      private
        No : integer;
      protected
        dbs : TADODataset;
        procedure  execute; override;
      public
        {
        }
      end;
    type TMultiRead = class( TThread )
      private
      {}
      protected
        procedure execute;  override;
      end;
    var
      Form1: TForm1;
      dbname : array[1..WellNO] of string;
      ddline : array[1..5] of integer;
      ados : array[1..WellNo] of TAdoDataSet;
      data: array [1..WellNo, 1..10, 1..12000] of real;implementation{$R *.dfm}
    procedure  TThdReadWData.execute;
    var
       count : integer;
       dirs, s : string;
    begin   dbs.Open;
       dbs.First;
       count := 0;
       while not dbs.Eof do
       begin
          inc(count);
          data[No, 1, count] := dbs.fieldByName('BZJS').asfloat;
          data[No, 2, count] := dbs.fieldByName('CZJS').asfloat;
              ....
          dbs.Next;
       end;
       dbs.Close;
       ddline[No] := count;   showmessage('number '+ inttostr(No) + 'finished ');
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
       mulread : TMultiRead;
    begin
       mulread := TMultiRead.Create(false);
       mulread.WaitFor;
       mulread.Free;
    end;procedure TMultiRead.execute;
    var
       trwds : array[1..WellNo] of TThdReadWData;
       i : integer;
       s ,dirs: string;
    //   t : Boolean;
    begin
       for i:=1 to WellNo do
       begin
          dirs := ExtractFilePath(Application.ExeName);
          s := dirs + 'File' + IntTostr(i) + '.mdb';
          ados[i].ConnectionString := 'Provider=MSDASQL.1;Persist Security Info=False;Extended Properties="DSN=MyAccess;DBQ=' +
             s + ';DefaultDir=' +
             dirs + ';DriverId=25;FIL=MS Access;MaxBufferSize=2048;PageTimeout=5;UID=admin;"';
          ados[i].CommandType := cmdTable;
          ados[i].CommandText := 'DepthData';
          trwds[i] := TThdReadWData.Create(true);
    //      t := trwds[i].Terminated;
          trwds[i].No := i;
          trwds[i].dbs := ados[i];
       end;   for i:=1 to WellNo do
          trwds[i].Resume;   for i:=1 to WellNo do
       begin
          trwds[i].WaitFor;
       end;
       for i:=1 to WellNo do
       begin
          trwds[i].free;
       end;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      ados[1] := AdoDataSet1;     ados[2] := AdoDataSet2;
      ados[3] := AdoDataSet3;     ados[4] := AdoDataSet4;
      ados[5] := AdoDataSet5;  dbname[1] := 'File1.mdb';   dbname[2] := 'File2.mdb';
      dbname[3] := 'File3.mdb';   dbname[4] := 'File4.mdb';
      dbname[5] := 'File5.mdb';
    end;end.