Freigeben über


Behandlung von Nebenläufigkeitsproblemen bei Datenbanken in Updategrams (SQLXML 4.0)

Wie bei anderen Datenbankaktualisierungsmechanismen müssen Updategramme gleichzeitige Aktualisierungen von Daten in einer Mehrbenutzerumgebung behandeln. Updategrams verwenden das optimistische Parallelitätssteuerelement, das den Vergleich von Auswahlfelddaten als Momentaufnahmen verwendet, um sicherzustellen, dass die zu aktualisierenden Daten von einer anderen Benutzeranwendung seit dem Lesen aus der Datenbank nicht geändert wurden. Aktualisierungsdiagramme enthalten diese Momentaufnahmenwerte im <before-Block> der Updategrams. Vor dem Aktualisieren der Datenbank überprüft das Updatediagramm die Werte, die im <Before-Block> angegeben sind, anhand der Werte, die sich derzeit in der Datenbank befinden, um sicherzustellen, dass die Aktualisierung gültig ist.

Das optimistische Parallelitätssteuerelement bietet drei Schutzebenen in einem Updatediagramm: niedrig (keine), Zwischen- und Hoch. Sie können entscheiden, welche Schutzebene Sie benötigen, indem Sie das Updategram entsprechend angeben.

Niedrigste Schutzebene

Diese Stufe ist ein blindes Update, bei dem das Update ohne Verweis auf andere Aktualisierungen verarbeitet wird, die seit dem letzten Lesen der Datenbank vorgenommen wurden. In einem solchen Fall geben Sie nur die Primärschlüsselspalte(n) im <vorher> blockierten Block an, um den Datensatz zu identifizieren, und Sie geben die aktualisierten Informationen im <After-Block> an.

Beispielsweise ist die neue Kontakttelefonnummer im folgenden Updategram korrekt, unabhängig davon, was die Telefonnummer zuvor war. Beachten Sie, wie der <Vorblock> nur die Primärschlüsselspalte (ContactID) angibt.

<ROOT xmlns:updg="urn:schemas-microsoft-com:xml-updategram">  
<updg:sync >  
<updg:before>  
   <Person.Contact ContactID="1" />  
</updg:before>  
<updg:after>  
   <Person.Contact ContactID="1" Phone="111-111-1111" />  
</updg:after>  
</updg:sync>  
</ROOT>  

Mittlere Schutzebene

In dieser Schutzstufe vergleicht das Updatediagramm die aktuellen Werte der Daten, die mit den Werten in den Datenbankspalten aktualisiert werden, um sicherzustellen, dass die Werte nicht von einer anderen Transaktion geändert wurden, da der Datensatz von Ihrer Transaktion gelesen wurde.

Sie können diese Schutzebene erhalten, indem Sie die Primärschlüsselspalten und die Spalten angeben, die Sie im <vorherigen> Block aktualisieren.

In diesem Updatediagramm wird beispielsweise der Wert in der Spalte "Telefon" der Tabelle "Person.Contact" für den Kontakt mit "ContactID von 1" geändert. Der <Vorblock> gibt das Phone-Attribut an, um sicherzustellen, dass dieser Attributwert dem Wert in der entsprechenden Spalte in der Datenbank entspricht, bevor der aktualisierte Wert angewendet wird.

<ROOT xmlns:updg="urn:schemas-microsoft-com:xml-updategram">  
<updg:sync >  
<updg:before>  
   <Person.Contact ContactID="1" Phone="398-555-0132" />  
</updg:before>  
<updg:after>  
   <Person.Contact ContactID="1" Phone="111-111-1111" />  
</updg:after>  
</updg:sync>  
</ROOT>  

Hohes Schutzniveau

Ein hoher Schutz stellt sicher, dass der Datensatz seit dem letzten Lesen des Datensatzes der Anwendung gleich bleibt (d. a., da Die Anwendung den Datensatz gelesen hat, wurde er von keiner anderen Transaktion geändert).

Es gibt zwei Möglichkeiten, diesen hohen Schutz vor gleichzeitigen Updates zu erhalten:

  • Geben Sie zusätzliche Spalten in der Tabelle im <vorherigen> Block an.

    Wenn Sie zusätzliche Spalten im <vorherigen> Block angeben, vergleicht das Updatediagramm die Werte, die für diese Spalten angegeben sind, mit den Werten, die sich in der Datenbank befanden, bevor die Aktualisierung angewendet wird. Wenn sich eine der Datensatzspalten seit dem Lesen des Datensatzes geändert hat, führt das Updatediagramm die Aktualisierung nicht aus.

    Das folgende Updategram aktualisiert z. B. den Schichtnamen, gibt jedoch zusätzliche Spalten (StartTime,EndTime) im <vorherigen> Block an, wodurch ein höherer Schutz vor gleichzeitigen Updates angefordert wird.

    <ROOT xmlns:updg="urn:schemas-microsoft-com:xml-updategram">  
    <updg:sync >  
    <updg:before>  
       <HumanResources.Shift ShiftID="1"   
                 Name="Day"   
                 StartTime="1900-01-01 07:00:00.000"   
                 EndTime="1900-01-01 15:00:00.000" />  
    </updg:before>  
    <updg:after>  
       <HumanResources.Shift Name="Morning" />  
    </updg:after>  
    </updg:sync>  
    </ROOT>  
    

    In diesem Beispiel wird die höchste Schutzebene angegeben, indem alle Spaltenwerte für den Datensatz im <vorherigen> Block angegeben werden.

  • Geben Sie die Zeitstempelspalte (sofern verfügbar) im <vorherigen> Block an.

    Anstatt alle Datensatzspalten im <before> Block anzugeben, können Sie einfach die Zeitstempelspalte (sofern die Tabelle einen hat) zusammen mit den Primärschlüsselspalten im <vorherigen> Block angeben. Die Datenbank aktualisiert die Zeitstempelspalte nach jeder Aktualisierung des Datensatzes auf einen eindeutigen Wert. In diesem Fall vergleicht das Updatediagramm den Wert des Zeitstempels mit dem entsprechenden Wert in der Datenbank. Der in der Datenbank gespeicherte Zeitstempelwert ist ein Binärwert. Daher muss die Zeitstempelspalte im Schema als dt:type="bin.hex", dt:type="bin.base64", oder sql:datatype="timestamp". (Sie können entweder den xml Datentyp oder den Microsoft SQL Server-Datentyp angeben.)

So testen Sie das Updategramm

  1. Erstellen Sie diese Tabelle in der tempdb-Datenbank :

    USE tempdb  
    CREATE TABLE Customer (  
                 CustomerID  varchar(5),  
                 ContactName varchar(20),  
                 LastUpdated timestamp)  
    
  2. Fügen Sie diesen Beispieldatensatz hinzu:

    INSERT INTO Customer (CustomerID, ContactName) VALUES   
                         ('C1', 'Andrew Fuller')  
    
  3. Kopieren Sie das folgende XSD-Schema, und fügen Sie es in Editor ein. Speichern Sie sie als ConcurrencySampleSchema.xml:

    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"  
                xmlns:sql="urn:schemas-microsoft-com:mapping-schema">  
      <xsd:element name="Customer" sql:relation="Customer" >  
       <xsd:complexType>  
            <xsd:attribute name="CustomerID"    
                           sql:field="CustomerID"   
                           type="xsd:string" />   
    
            <xsd:attribute name="ContactName"    
                           sql:field="ContactName"   
                           type="xsd:string" />  
    
            <xsd:attribute name="LastUpdated"   
                           sql:field="LastUpdated"   
                           type="xsd:hexBinary"   
                 sql:datatype="timestamp" />  
    
        </xsd:complexType>  
      </xsd:element>  
    </xsd:schema>  
    
  4. Kopieren Sie den folgenden Updategramcode in Editor, und speichern Sie ihn als ConcurrencySampleTemplate.xml im selben Verzeichnis, in dem Sie das im vorherigen Schritt erstellte Schema gespeichert haben. (Beachten Sie den folgenden Zeitstempelwert für LastUpdated in Ihrer Beispiel-Kundentabelle. Kopieren Sie also den tatsächlichen Wert für LastUpdated aus der Tabelle, und fügen Sie ihn in das Updategram ein.)

    <ROOT xmlns:updg="urn:schemas-microsoft-com:xml-updategram">  
    <updg:sync mapping-schema="SampleSchema.xml" >  
    <updg:before>  
       <Customer CustomerID="C1"   
                 LastUpdated = "0x00000000000007D1" />  
    </updg:before>  
    <updg:after>  
       <Customer ContactName="Robert King" />  
    </updg:after>  
    </updg:sync>  
    </ROOT>  
    
  5. Erstellen und verwenden Sie das SQLXML 4.0-Testskript (Sqlxml4test.vbs), um die Vorlage auszuführen.

    Weitere Informationen finden Sie unter Verwenden von ADO zum Ausführen von SQLXML 4.0-Abfragen.

Dies ist das entsprechende XDR-Schema:

<?xml version="1.0" ?>  
<Schema xmlns="urn:schemas-microsoft-com:xml-data"  
        xmlns:dt="urn:schemas-microsoft-com:datatypes"  
        xmlns:sql="urn:schemas-microsoft-com:xml-sql">  
<ElementType name="Customer" sql:relation="Customer" >  
    <AttributeType name="CustomerID" />  
    <AttributeType name="ContactName" />  
    <AttributeType name="LastUpdated"  dt:type="bin.hex"   
                                       sql:datatype="timestamp" />  
    <attribute type="CustomerID" />  
    <attribute type="ContactName" />  
    <attribute type="LastUpdated" />  
</ElementType>  
</Schema>  

Siehe auch

Überlegungen zur Updategramsicherheit (SQLXML 4.0)