Announcement

Collapse
No announcement yet.

ADO und SQL- Server 7 Deadlocks

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • ADO und SQL- Server 7 Deadlocks

    Ich arbeite mit ADO 2.5 und SQL-Server 7. Ich habe eine Anwendung geschrieben, die die Belastung des Servers simulieren soll. Hierzu werden miteinander verknüfpte Tabellen per Zufallsgenerator verändert. Ich benutze TADOTable und TADOQuery. Das Programm soll auf mehreren Rechnern laufen. Sind mehrere Clients des Programmes aktiv, so kommt es häufig zu Deadlocks.
    Wie kann ich diese Deadlocks auf dem Client abfangen, um ein Rollback und die Wiederholung der Transaktion zu ermöglichen?

    Hier der Beispiel- Quelltext:

    While Bitbtn1.Tag = 0 do begin

    Application.ProcessMessages;

    EndeI:=Random(4);

    If EndeI = 0 then EndeI:=1;

    for i:=1 to EndeI do begin

    case i of

    1: begin

    ...

    2: begin

    with ADOTable2 do

    begin

    Application.ProcessMessages;

    jj:= Random(Trunc((RecordCount)/10));

    if jj=0 then jj:=1;

    for J:= 1 to jj

    do begin

    Close;

    Open;

    DisableControls;

    EndeK:=Random(RecordCount);

    if EndeK=0 then EndeK:=1;

    for k:=1 to EndeK do Next;

    EnableControls;

    Application.ProcessMessages;

    if bitbtn1.Tag = 1 then Abort;

    try

    ADOConnection1.BeginTrans;

    Edit;

    Post;

    Edit;

    FieldByName('Bezeichnung').AsString:='Bezeichnung: '+IntToStr(k);

    FieldByName('Kostenanschlag_DM').Value:=k;

    Post;

    ADOConnection1.CommitTrans;

    except

    ADOConnection1.RollbackTrans;

    Close;

    Open;

    MessageDlg('T_E: Datensatz gesperrt - bitte wiederholen.', mtInformation,[mbOk], 0);

    end;

    Application.ProcessMessages;

    end;

    end; // With ADOTable2

    end; // 2:

    3: begin

    ....

    end;

    ...

    usw.

    Ich wäre dankbar für eine Lösung.

    Volker Lauckner


  • #2
    Ist für den SQL-Server schon der Service Pack #2 installiert? Denn ohne Service Pack ist der Server noch ziemlich Fehlerhaft.

    Abfrage der Version über folgende SQL-Anweisung: SELECT @@VERSION

    Bei mir kommt folgender String zurück:

    Microsoft SQL Server 7.00 - 7.00.842 (Intel X86)
    Mar 2 2000 06:49:37
    Copyright (c) 1988-1998 Microsoft Corporation
    Standard Edition on Windows NT 4.0 (Build 1381: Service Pack 6

    Comment


    • #3
      Hallo,

      generell sind derartige Testprogramm mit Vorsicht zu geniessen, wenn TADOTable auf eine komplette Tabelle losgelassen wird. Wenn dann noch eine Client-Side-Cursor eingesetzt wird, holt sich das RecordSet-Objekt alle Daten der Tabelle, um dann nur einen Datensatz zu editieren. Bei der Vielzahl an Konfigurations-Optionen sind in einem derartigen Fall auch verschiednen Ergebnisse möglich.

      Nun zum eigentlichen Problem. Je nach dem verwendete OLE DB-Provider und der gewählten Konfiguration wird bei ADO Express nicht jeder OLE DB/ADO-Fehler in eine Exception umgesetzt. Daher liegt man mit dem direkten Abfragen der Errors-Kollektion von ADO nach einem Aufruf auf der sicheren Seite. Das könnte so aussehen:
      <pre>
      ...
      with ADOConnectionSQLOLEDB do
      for iError := 0 to Errors.Count - 1 do
      sError := sError + Errors[iError].Description + #10#13;
      ShowMessage(sError);
      </pre&gt

      Comment


      • #4
        Vielen Dank für die Hinweise.

        Das Auslesen der gesamten Tabelle ist notwendig, wenn man die Features von dxDBGrid und dxDBTreeList
        (DevExpress) nutzen möchte (Gruppieren, Multisort usw. setzen LoadAllRecords voraus).

        Eine ähnliche Fehlerbehandlung hatte ich schon drin. Es werden auch fast alle Fehler abgefangen.
        Wenn jedoch der Server meine Transaktion mit "... Sie wurden als Deadlockopfer ausgewählt..." abbricht,
        dann habe ich noch keine Möglichkeit gefunden, dies abzufangen.

        Volker Lauckne

        Comment


        • #5
          Hi Volker,

          ich arbeite auch mit den DeveloperExpress Komponenten. Natürlich auch im egoLoadAllRecords. Wie fürst Du ein Refresh des aktuellen oder aller Datensätzen durch ? Habe da immer ein paar Probleme. Auch bei einem Delete, bleibt der gelöschte Datenssatz im Grid stehen. Wie ist das bei Dir ?

          Bis dann
          Mathia

          Comment


          • #6
            Hallo BlueBit,

            Ich hatte dieses Problem noch nicht.

            Ich habe die Properties Options.egoSmartReload und Options.egoSmartRefresh auf True gesetzt, ebenso Options.egoCanDelete und Options.egoConfirmDelete.

            Volke

            Comment


            • #7
              Hallo Volker,

              danke für die Rückmeldung. Ich habe die Jungs von DevExpress mal angeschrieben. Habe auch gleich Antwort erhalten, die Jungs meinen wenn man den Record direkt über dir Delete - Methode von TDataSet entfernt, muss anschließend entwender der "Focused Node" über Delete -Methode (dxDbGridNode) entfernt werden oder man verwendet die Methode FullRefresh.

              Mit der FullRefresh - Geschichte läuft es tadellos, da das Grid eine optimieren Refresh durchführt, hat man auch bei einer großen Datenmenge keine Timing - Probleme.

              Du musst Dir unbedingt die neue Version vom QuantumGrid anschauen, ist wirklich sehr gut geworden. Da der Dollar ja jetzt wieder bei fast 2 DM's gelandet ist, habe ich gleich das Update auf die Pro Version gekauft, auch die neuen Edit Controls die ja jetzt dabei sind. Einfach phantastisch. Musst Du Dir unbedingt mal anschauen.

              Bis dann
              Mathia

              Comment

              Working...
              X