Announcement

Collapse
No announcement yet.

Zwei User auf gleichem Datensatz - MSSQL2000

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

  • Zwei User auf gleichem Datensatz - MSSQL2000

    <p>Hallo,</p>
    <p>ich habe per ADO Zugriff auf eine Datenbank von einem SQLSERVER2000. Nun ist
    folgendes Problem. Zwei User stehen auf dem gleichen Datensatz und bearbeiten
    diesen. Postet nun einer, ist alles OK. Postet der zweite, kommt wie erwartet
    die Meldung &quot;Fehler bei der &Uuml;berpr&uuml;fung auf vollst&auml;ndige
    Parallelit&auml;t. Die Zeile wurde au&szlig;erhalb dieses Cursors ge&auml;ndert&quot;
    und die Datenbank bleibt im Editmodus. Nur versucht es dieser User nun erneut,
    so hat er Erfolg. Kann mir das jemand erkl&auml;ren?? Was kann man dagegen tun?<br>
    </p>
    <p><font face="Courier New, Courier, mono">object ADOConnection: TADOConnection<br>
    Connected = True<br>
    ConnectionString = <br>
    'Provider=SQLOLEDB.1;Persist Security Info=False;User ID=Test;' +<br>
    'Initial Catalog=SQLData;Data Source=SQLSERVER'<br>
    CursorLocation = clUseServer<br>
    LoginPrompt = False<br>
    Mode = cmShareDenyWrite<br>
    Provider = 'SQLOLEDB.1'<br>
    end<br>
    </font><font face="Courier New, Courier, mono"><br>
    object ADOTable: TADOTable<br>
    Connection = ADOConnection<br>
    CursorLocation = clUseServer<br>
    </font><font face="Courier New, Courier, mono">LockType = ltBatchOptimistic<br>
    TableName = 'KUNDEN'<br>
    end</font><br>
    </p>
    <p>Vielen Dank schon mal,</p>
    <p>Mario Noack</p>
    Schöne Grüße, Mario

  • #2
    Hallo,

    die Erklärung für dieses Verhalten wird sofort sichtbar, wenn man sich mit dem MSSQL-Tool <i>Profiler</i> die von ADO automatisch generierte UPDATE-Anweisung anschaut. Als WHERE-Kriterium werden neben dem Primärschlüsselwert auch <b>alle</b> anderen Spalten herangezogen, d.h. das UPDATE liefert immer dann RowsAffected = 0 zurück, wenn in der Zwischenzeit ein anderer Benutzer eine <b>beliebige</b> Spalte des gleichen Datensatzes geändert hat. Um das Problem zu lösen, gibt es verschiedene Ansätze:

    1. Pessimistische Datensatzsperre: <b>clUseServer</b> + <b>ltPessimistic</b>. Der MSSQL Server setzt dabei automatisch ein Update-Lock, so dass nur die Session ein UPDATE absetzen darf, die zuerst das SELECT ausgelöst hat. Dieser Weg hat jedoch Nebenwirkungen (siehe clUseServer).

    2. Update Criteria = <b>adCriteriaKey</b> (nur Primärschlüssel als WHERE-Kriterium verwenden). In diesem Fall kann jeder Speichern, allerdings ohne zu Wissen, ob in der Zwischenzeit ein anderer Benutzer den gleichen Datensatz geändert hat.
    <pre>
    with ADODataSet1.Recordset do
    begin
    Properties['Update Criteria'].Value := adCriteriaKey;
    Properties['Update Resync'].Value := adResyncAll;
    end;
    </pre&gt

    Comment


    • #3
      Bei dem Versuch von <b>ADODataSet.Recordset.Properties['Update Criteria'].Value := adCriteriaKey;</b> bekomme ich leider die Meldung: <b>Ein Objekt, das dem angeforderten Namen oder dem Ordinalverweis entspricht, kann nicht gefunden werden.</b> Ich habe zwar ein Gefühl, was es bedeutet, aber was ich dagegeben tun kann, weiß ich ehrlich gesagt nicht.<p>
      Schöne Grüße, Mario Noac
      Schöne Grüße, Mario

      Comment


      • #4
        Hallo,

        ich bin davon ausgegangen, dass die Anwendung generell <b>clUseClient</b> für die TADODataSet-Eigenschaft CursorLocation verwendet und ausserdem der Zugriff auf die Microsoft SQL Server 2000-Datenbank über SQLOLEDB (OLE DB Provider for Microsoft SQL Server) erfolgt. Da mir die o.g. Fehlermeldung im Zusammenhang mit dem MS SQL Server noch nicht untergekommen ist, würde ich folgendes prüfen: <br>
        1. Wird clUseClient für die Eigenschaft CursorLocation verwendet? Wenn nicht, ändern!<br>
        2. Taucht der Eintrag <i>Provider=SQLOLEDB.1</i> im ConnectionString auf? Wenn nicht, ändern.<br>
        3. Falls 1+2 nicht zum Erfolg führt, ist MDAC 2.6 auf diesem Rechner installiert?

        Auch wenn es verwirrend klingt, sollte clUseServer generell nur bei Desktop-Datenbanken wie ACCESS und clUseClient generell bei SQL-Datenbanken genutzt werden. Nur dann, wenn clUseClient aktiv ist, stehen die Objekte und Funktionen der <i>OLE DB Client Cursor Engine</i> zur Verfügung. Mit dem "Verzicht" auf clUseClient verzichtet man auf ca. 75% der ADO-Funktionalität.

        P.S: Mit Microsoft .NET und ADO.NET steht nur noch clUseClient zur Verfügung (das "veraltete" clUseServer kommt in diesem Design nicht mehr vor)

        Comment


        • #5
          Hallo Andreas,<p>
          wir verwenden <b>clUseServer</b>. Die Größe und der Umfang der Datenbanken lassen bei uns auch nicht so ohne weiteres andere Entscheidungen zu. In der Dokumentation zu ADO 2.7 habe ich keinen Hinweis darauf gefunden, dass <b>clUseServer</b> ausläuft. Woher ist diese Information?<p>
          Generell fehlt mir noch ein wenig das Verständnis dafür, warum der Clientcursor besser sein soll, speziell bei größeren Datenbanken. Es ist sicherlich richtig, dass der ClientCursor mehr Funktionen bietet, jedoch kann es doch nicht Sinn und Zweck sein, Datenbanken beliebiger Größe auf die Clients zu kopieren, nur um diese Mehrfunktionalität zu nutzen. Was ist, wenn die Datenbank nicht mehr temporär auf den Client passt? Oder verstehe ich hier vielleicht den ClientCursor nicht richtig??<p>
          Fragende Grüße, Mario Noac
          Schöne Grüße, Mario

          Comment


          • #6
            Achso, noch ein Beispiel:<p>
            Das öffnen einer Table im Grid dauert bei mir mit ServerCursor ca. 2 Sekunden. Das ist voll OK. Stelle ich jedoch auf Client um, so habe ich trotz 100MBit eine Mehrzeit von ca. 10 Sekunden. Und das ist beileibe nicht die größte Datenbank. Kann dies das neue Konzept sein?<p>
            Andreas, verstehe mich nicht falsch, aber ich wehre mich ein wenig gegen die Client-Geschichte. Ich glaube Deine Argumente, aber für einen Kunden brauche ich Beweise. Und wenn 2 (Server) gegen 2+10 Sekunden (Client) stehen, werden mir zwangsweise die Hände gebunden
            Schöne Grüße, Mario

            Comment


            • #7
              Hallo,

              generell sollte man bei einer SQL-Datenbank immer nur eine Ergebnismenge erzeugen, die nur aus den tatsächlich benötigten Datensätzen besteht. Anstelle ein <i>SELECT * FROM Tabelle</i> abzusetzen, sollte immer zu <i>SELECT x,y,z FROM Tabelle <b>WHERE...</b></i> zurückgegriffen werden.

              &gt;Und wenn 2 (Server) gegen 2+10 Sekunden (Client) stehen, werden<br>
              &gt;mir zwangsweise die Hände gebunden.

              Mit <b>clUseServer</b> wird das Problem nicht gelöst, sondern nur versteckt. Denn der SQL-Server muss mit einer Ergebnismenge hantieren, die viel zu viel Daten enthält. Mit clUseServer schränkt das Programm nur die Datenmenge ein, die sofort zum Client transportiert wird. Es ist doch unbestritten deutlich effektiver, auf der Seite des SQL-Servers erst gar nicht so grosse Ergebnismengen entstehen zu lassen.

              Wenn über eine geeignete WHERE-Einschränkung nur die Datensätze abgerufen werden, die der Client für eine bestimmte Aufgabe tatsächlich benötigt, gibt es zwischen clUseServer und clUseClient keine Zeitunterschiede.

              &gt;Woher ist diese Information?

              ADO.NET ist nicht der direkte technische Nachfolger von ADO, auch wenn es viele Ähnlichkeiten gibt. Aus diesem Grund muss ADO.NET auch nicht abwärtskompatibel zu ADO sein, so dass "Ballast" entsorgt wurde (in einer dreischichtigen Architektur kann es allein aus technischen Gründen keine serverseitigen Cursor geben). Unter <i>http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/adonetprogmsdn.asp</I> ist zum Beispiel folgendes zu lesen: "<i>Note that ADO.NET version 1.0 does not expose a scrollable, updateable server-side cursor. Applications that require scrolling and positioned updates on the client side generally involve user interaction. Because server-side cursors require state to be held on the server, your application will not be robust or scalable if it must hold those valuable resources while users interact with the data on the client side. Most applications that currently use scrollable server-side cursors on the client could be much more efficiently written according to one of the following designs....</i>" (Zitat Ende)

              Comment


              • #8
                Hallo,<br>
                als Empfehlung an alle (und etwas Werbung für <i>Der Entwickler</i>), die Interesse an näheren Details und praktischen Tips zum Umgang mit dem ADO-Cusor haben:<br>
                <i>Der Entwickler, Jan/Feb 2002, S.28, A.Kosch, ADO: Mehr als ein Datenbanktreiber - Teil2, Auswahl und Verwendung des Cursors</i><br>
                Dieser Artikel enthält eine recht umfangreiche und nützliche Abhandlung zu diesem Thema.<br>
                Ich denke, diese Ausgabe müsste noch zu haben sein

                Comment

                Working...
                X