Einzelnen Beitrag anzeigen

romber

Registriert seit: 15. Apr 2004
Ort: Köln
1.164 Beiträge
 
Delphi 10 Seattle Professional
 
#1

Daten sammeln und in MS SQL-Datenbank hinzufügen???

  Alt 24. Jul 2009, 15:24
Datenbank: MS SQL Server • Version: 2008 • Zugriff über: ADO
Hallo!

Ich habe in meinem Programm mehrere Threads, die permanent laufen und XML-Daten liefern. Diese Daten muss ich einer MS SQL-Datenbank hinzufügen. Da es sich beim Datenbankserver um einen Remoteserver handelt und das direkte Hinzufügen im selben Thread desen Ablauf verzögern könnte (was ich in meinem Fall unbedingt vermeiden muss), habe ich einen anderen Thread erstellt, der die Daten einsammelt und der DB hinzufügt. Dafür habe ich zusätzlich noch eine TStringList erstellt, in der die für DB bestimmte Daten landen. Alle Threads fügen die XML-Daten dieser TStringList hinzu. Der DB-Thread greift immer wieder auf diese Liste zu, prüft ob neue Daten vorhanden sind und wenn was neues gibt, leitet die Daten an die DB weiter.

Problem: Einige Datensätze aus der TStringList landen doppelt in die Datenbenk, während einige gar nicht hinzufügt werden. Dabei konnte ich sicherstellen, dass es keine gleiche Daten in der TStringList gibt. Was mache ich falsch?


Liste für die Daten und CriticalSection:

Delphi-Quellcode:
...
var
  lstDBData: TStringList;
  csDBData: TCriticalSection;
So werden die Daten in die Liste hinzufügt:

Delphi-Quellcode:
...
  csDBData.Enter;
  try
    lstDBData.Add(XMLData);
  finally
    csDBData.Leave;
  end;
Thread, der die Daten verarbeitet:

Delphi-Quellcode:
type
  TAddDataToDB = class(TThread)
  constructor Create(CreateSuspended: Boolean; AAllowUpdate: Boolean);
  private
    AllowUpdate: Boolean;
  protected
    procedure Execute; override;
end;

constructor TAddDataToDB.Create(CreateSuspended: Boolean; AAllowUpdate: Boolean);
begin
  inherited Create(CreateSuspended);
  FreeOnTerminate := true;
  AllowUpdate := AAllowUpdate;
end;

procedure TAddDataToDB.Execute;
var
  ADO: TADOTable;
  XMLDoc: IXMLDocument;
  XMLRoot: IXMLNode;
begin
  CoInitialize(nil);

  ADO := TADOTable.Create(nil);
  ADO.ConnectionString := 'Provider=SQLOLEDB.1;Password=' + DB_PASSWORD + ';' +
                          'Persist Security Info=True;User ID=' + DB_USERNAME + ';' +
                          'Initial Catalog=' + DB_NAME + ';' +
                          'Data Source=' + DB_HOST;
  ADO.TableName := DB_TABLE;

  while not Terminated do
  begin
    if lstDBData.Count > 0 then
    begin
      ADO.Active := true;
      repeat
        if Length(lstDBData.Strings[0]) > 0 then
        begin
          //Hier wird XML analysieret, zerteilt und in der DB hinzufügt
        end;
        //Verarbeite Daten aus der Liste entfernen
        csDBData.Enter;
        try
          lstDBData.Delete(0);
        finally
          csDBData.Leave;
        end;
      until lstDBData.Count = 0;
      ADO.Active := false;
    end;
    Sleep(10);
  end;

  ADO.Free;
end;
  Mit Zitat antworten Zitat