Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (Deutsch) » SQL Anywhere Server - SQL-Benutzerhandbuch » Datenbanken erstellen » Transaktionen und Isolationsstufen verwenden » Praktische Einführung in Isolationsstufen

 

Praktische Einführung: Auswirkung von Sperren

In dieser praktischen Einführung haben sowohl der "Accountant" als auch der "Sales Manager" Aufgaben, welche die Tabellen "SalesOrder" und "SalesOrderItems" betreffen. Der "Accountant" muss die Beträge der Kommissionszahlungen überprüfen, die dem Verkaufspersonal für die im April 2001 durchgeführten Verkäufe zustehen. Der "Sales Manager" bemerkt, dass sich einige Aufträge nicht in der Datenbank befinden, und möchte diese hinzufügen.

Bei diesen Vorgängen wird gezeigt, wie Phantomsperren funktionieren. Eine Phantomsperre ist eine gemeinsame Sperre, die auf eine indizierte Suchposition gesetzt wird, um Phantomzeilen zu verhindern. Wenn eine Transaktion mit Isolationsstufe 3 Zeilen auswählt, die ein bestimmtes Kriterium erfüllen, bringt der Datenbankserver Anti-Einfügesperren an, damit andere Transaktionen keine Zeilen einfügen können, die ebenfalls diesem Kriterium entsprechen. Die Anzahl der für Ihre Transaktion gesetzten Sperren hängt sowohl vom Suchkriterium als auch vom Aufbau Ihrer Datenbank ab.

Hinweis

Damit diese praktische Einführung funktioniert, darf die Option Datenbanksperren automatisch freigeben in Interactive SQL (Extras » Optionen » SQL Anywhere) nicht aktiviert sein.

  1. Starten Sie zwei Instanzen von Interactive SQL. Siehe die Schritte 1 bis 4 unter Praktische Einführung: Nicht-wiederholbare Lesevorgänge

  2. Stellen Sie die Isolationsstufe sowohl im Fenster des "Sales Managers" als auch in dem des "Accountant" auf 2, indem Sie den folgenden Befehl ausführen.

    SET TEMPORARY OPTION isolation_level = 2;
  3. Die Handelsvertreter erhalten monatlich eine Provision, die als Prozentsatz der Umsätze für den jeweiligen Monat berechnet wird. Der "Accountant" bereitet die Provisionszahlungen für April 2001 vor. Seine erste Aufgabe besteht darin, den Gesamtumsatz jedes Vertreters für diesen Monat zu berechnen.

    Führen Sie den folgenden Befehl im Fenster des "Accountants" aus: Die Preise, Bestellinformationen und Daten der Angestellten sind in getrennten Tabellen gespeichert. Verknüpfen Sie diese Tabellen unter Verwendung von Fremdschlüsselbeziehungen, um die notwendigen Teilinformationen zusammenzusetzen.

    SELECT EmployeeID, GivenName, Surname,
       SUM(SalesOrderItems.Quantity * UnitPrice)
          AS "April sales"
    FROM Employees
       KEY JOIN SalesOrders
       KEY JOIN SalesOrderItems
       KEY JOIN Products
    WHERE '2001-04-01' <= OrderDate
       AND OrderDate < '2001-05-01'
    GROUP BY  EmployeeID, GivenName, Surname
    ORDER BY EmployeeID;
    EmployeeID GivenName Surname April sales
    129 Philip Chin 2160.00
    195 Marc Dill 2568.00
    299 Rollin Overbey 5760.00
    467 James Klobucher 3228.00
    ... ... ... ...
  4. Der "Sales Manager" bemerkt, dass ein großer Auftrag von Philip Chin nicht in die Datenbank eingegeben wurde. Philip will seine Provision immer pünktlich erhalten, also gibt der "Sales Manager" den fehlenden Auftrag ein, der am 25. April gebucht wurde.

    Führen Sie im Fenster des "Sales Managers" die folgenden Befehle aus. Die Bestellung und die Elemente werden in getrennten Tabellen eingegeben, da eine Bestellung viele Elemente umfassen kann. Sie sollten zuerst den Eintrag für die Bestellung durchführen, bevor Sie Elemente hinzufügen. Um die referenzielle Integrität aufrechtzuerhalten, gestattet der Datenbankserver eine Transaktion, mit der Elemente einer Bestellung hinzufügt werden, nur dann, wenn diese Bestellung bereits vorhanden ist.

    INSERT into SalesOrders
    VALUES ( 2653, 174, '2001-04-22', 'r1',
          'Central', 129);
    INSERT into SalesOrderItems
    VALUES ( 2653, 1, 601, 100, '2001-04-25' );
    COMMIT;
  5. Der "Accountant" kann nicht wissen, dass der "Sales Manager" gerade einen neuen Auftrag hinzugefügt hat. Wäre der neue Auftrag früher eingegeben worden, so wäre er in der Berechnung von Philip Chins Aprilumsätzen berücksichtigt.

    Berechnen Sie im Fenster des "Accountants" noch einmal den Gesamtumsatz für den Monat April. Verwenden Sie den gleichen Befehl. Es wird Ihnen auffallen, dass Philip Chins Aprilumsatz plötzlich $4560,00 beträgt.

    EmployeeID GivenName Surname April sales
    129 Philip Chin 4560.00
    195 Marc Dill 2568.00
    299 Rollin Overbey 5760.00
    467 James Klobucher 3228.00
    ... ... ... ...

    Nehmen wir an, dass der "Accountant" alle im April gebuchten Aufträge markiert, um anzuzeigen, dass die Provision bezahlt wurde. Der vom "Sales Manager" gerade eingegebene Auftrag wird in der zweiten Suchabfrage gefunden und als bezahlt markiert, obwohl er nicht in Phillips Gesamtumsatz für den Monat April berücksichtigt wurde.

  6. Bei Isolationsstufe 3 bringt der Datenbankserver Anti-Einfügesperren an, um zu gewährleisten, dass keine anderen Transaktionen eine Zeile hinzufügen können, die den Such- oder Auswahlkriterien entspricht.

    Führen Sie im Fenster des "Sales Managers" die folgenden Befehle aus, um den neuen Auftrag zurückzunehmen:

    DELETE
    FROM SalesOrderItems
    WHERE ID = 2653;
    DELETE
    FROM SalesOrders
    WHERE ID = 2653;
    COMMIT;
  7. Führen Sie im Fenster des "Accountants" die folgenden zwei Befehle aus:

    ROLLBACK;
    SET TEMPORARY OPTION isolation_level = 3;
  8. Führen Sie im Fenster des "Accountants" dieselbe Abfrage wie vorhin aus.

    SELECT EmployeeID, GivenName, Surname,
       SUM(SalesOrderItems.Quantity * UnitPrice)
          AS "April sales"
    FROM Employees
       KEY JOIN SalesOrders
       KEY JOIN SalesOrderItems
       KEY JOIN Products
    WHERE '2001-04-01' <= OrderDate
       AND OrderDate < '2001-05-01'
    GROUP BY  EmployeeID, GivenName, Surname;

    Da Sie die Isolationsstufe auf 3 gesetzt haben, bringt der Datenbankserver automatisch Anti-Einfügesperren an, die gewährleisten, dass der "Sales Manager" keine April-Aufträge eingeben kann, solange der "Accountant" seine Transaktion nicht beendet hat.

  9. Kehren Sie zum "Sales Manager"-Fenster zurück. Versuchen Sie nochmals, die fehlende Bestellung von Phillip Chin einzugeben.

    INSERT INTO SalesOrders
    VALUES ( 2653, 174, '2001-04-22',
             'r1','Central', 129);

    Das "Sales Manager"-Fenster reagiert nicht mehr und der Vorgang wird nicht abgeschlossen. Klicken Sie in der Symbolleiste auf SQL-Anweisung unterbrechen (oder wählen Sie SQL » Stopp), um diesen Eintrag zu unterbrechen.

  10. Der "Sales Manager" kann den Auftrag zwar nicht im April eingeben, aber der Eintrag im Mai sollte doch möglich sein.

    Ändern Sie das Befehlsdatum auf 05. Mai und versuchen Sie es noch einmal.

    INSERT INTO SalesOrders
    VALUES ( 2653, 174, '2001-05-05', 'r1',
          'Central', 129);

    Das "Sales Manager"-Fenster reagiert nicht mehr. Klicken Sie in der Symbolleiste auf SQL-Anweisung unterbrechen (oder wählen Sie SQL » Stopp), um diesen Eintrag zu unterbrechen. Obwohl der Datenbankserver nicht mehr als die notwendigen Sperren zum Vermeiden von Einfügungen anbringt, haben diese Sperren das Potenzial, sich mit vielen anderen Transaktionen zu überlagern.

    Der Datenbankserver bringt Sperren in Tabellenindizes an. Er bringt zum Beispiel eine Phantomsperre in einem Index an, damit keine Zeile direkt davor eingefügt werden kann. Ist aber kein entsprechender Index vorhanden, so muss jede Zeile in der Tabelle gesperrt werden.

    Es gibt Situationen, in denen Anti-Einfügesperren einige Einfügungen in einer Tabelle verhindern, andere aber erlauben.

  11. Der "Sales Manager" möchte der Bestellung 2651 ein zweites Element hinzufügen. Verwenden Sie den folgenden Befehl.

    INSERT INTO SalesOrderItems
    VALUES ( 2651, 2, 302, 4, '2001-05-22' );

    Das "Sales Manager"-Fenster reagiert nicht mehr. Klicken Sie in der Symbolleiste auf SQL-Anweisung unterbrechen (oder wählen Sie SQL » Stopp), um diesen Eintrag zu unterbrechen.

  12. Schließen Sie diese praktische Einführung ab, indem Sie alle Änderungen rückgängig machen, damit die SQL Anywhere-Beispieldatenbank nicht geändert wird. Führen Sie den folgenden Befehl im Fenster des "Sales Managers" aus.

    ROLLBACK;

    Geben Sie den gleichen Befehl im Accountant-Fenster ein.

    ROLLBACK;

Schließen Sie beide Fenster.