Megosztás a következőn keresztül:


Adatbázis egyidejű problémák kezelése Updategramokban (SQLXML 4.0)

A következőkre vonatkozik:SQL ServerAzure SQL Database

Más adatbázis-frissítési mechanizmusokhoz hasonlóan az updategramoknak is párhuzamos adatfrissítésekkel kell foglalkoznia többfelhasználós környezetben. Az updategramok az Optimistic Concurrency Control (Optimistic Concurrency Control) rendszert használják, amely a kiválasztott mezőadatok összehasonlítását használja pillanatképként, hogy biztosítsa a frissítendő adatokat egy másik felhasználói alkalmazás nem módosította, mióta az adatbázisból olvasták. Az updategramok ezeket a snapshot értékeket a <updategramok előtti> blokkjában tartalmazzák. Az adatbázis frissítése előtt a updategram ellenőrzi az előtte> blokkban megadott< értékeket az adatbázisban lévő aktuális értékekkel szemben, hogy megbizonyosodjon arról, hogy a frissítés érvényes-e.

Az Optimista Egyidejű Vezérlés három szintű védelmet kínál egy updategramban: alacsony (nincs), középszintű és magas. A frissítési programot ennek megfelelően meghatározva döntheted el, milyen szintű védelemre van szükséged.

A legalacsonyabb szintű védelem

Ez a szint vak frissítés, amelyben a frissítést feldolgozzák anélkül, hogy hivatkoznak az adatbázis utolsó olvasása óta végrehajtott frissítésekre. Ilyen esetben csak az első> blokkban található elsődleges kulcsoszlop(okat<) adjuk meg a rekord azonosítására, és a frissített információkat az <after> blokkban.

Például a következő frissítési kódban az új elérhetőségi telefonszám helyes, függetlenül attól, hogy korábban milyen volt a telefonszám. Figyeld meg, hogy az előtte<> blokk csak a fő kulcsoszlopot (ContactID) határozza meg.

<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>  

Középszintű védelem

Ebben a védettségi szinten a updategram összehasonlítja a frissített adatok aktuális értékét az adatbázis oszlop(i) értékeivel, hogy megbizonyosodjon róla, hogy a tranzakció olvasta el a rekordot egy másik tranzakció által, hogy az értékeket nem változtatta meg.

Ezt a védelmet úgy érheted el, ha megadod a fő kulcsoszlop(okat) és az általad frissített oszlopokat az <előtti> blokkban.

Például ez a updategram megváltoztatja a Person.Contact táblázat Telefon oszlopában az értéket a kapcsolat számára, amelynek ContactID értéke 1. Az <before> blokk megadja a Phone attribútumot, hogy biztosítsa, hogy ez az attribútum értéke egyezik az adatbázis megfelelő oszlopának értékével, mielőtt alkalmaznánk a frissített értéket.

<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>  

Magas szintű védelem

A magas szintű védelem biztosítja, hogy a rekord ugyanaz maradjon attól függően, hogy az alkalmazásod utoljára olvasta azt a bejegyzést (vagyis mivel a jelentkezésed elolvasta a rekordot, más tranzakció nem változtatta meg).

Kétféleképpen lehet ilyen magas szintű védelmet elérni az egyidejű frissítések ellen:

  • Határozz meg további oszlopokat a táblázatban az <előtti> blokkban.

    Ha az before blokkban további oszlopokat <adsz meg, az updategram összehasonlítja az ezekhez az oszlopokhoz megadott értékeket azokkal az adatbázisban lévő értékekkel, amelyek a frissítés alkalmazása előtt voltak.> Ha bármelyik rekordoszlop megváltozott azóta, hogy a tranzakciód felolvasta a rekordot, az updategram nem végzi el a frissítést.

    Például a következő updategram frissíti a shift nevet, de további oszlopokat (StartTime, EndTime) határoz meg az <előtti> blokkban, így magasabb szintű védelmet kér az egyidejű frissítések ellen.

    <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>  
    

    Ez a példa a legmagasabb szintű védelmet azzal határozza meg, hogy az előző> blokkban lévő rekord< összes oszlopértékét megadja.

  • Megadja az időbélyeg oszlopot (ha elérhető) az <előtte> blokkban.

    Ahelyett, hogy az előtti > blokkban megadnád az összes rekordoszlopot<, egyszerűen megadhatod az időbélyeg oszlopot (ha a táblán van), valamint az első kulcsoszlop(okat) az <előtti> blokkban. Az adatbázis minden frissítés után egyedi értékre frissíti az időbélyeg oszlopot. Ebben az esetben a updategram összehasonlítja az időbélyeg értékét az adatbázisban szereplő megfelelő értékkel. Az adatbázisban tárolt időbélyeg érték bináris érték. Ezért az időbélyeg oszlopot a sémában úgy kell megadni: dt:type="bin.hex", dt:type="bin.base64" vagy sql:datatype="timestamp". (Megadhatod az xml adattípust vagy a Microsoft SQL Server adattípust.)

A updategram teszteléséhez

  1. Hozzuk létre ezt a táblázatot a tempdb adatbázisban:

    USE tempdb  
    CREATE TABLE Customer (  
                 CustomerID  varchar(5),  
                 ContactName varchar(20),  
                 LastUpdated timestamp)  
    
  2. Add hozzá ezt a mintalemezt:

    INSERT INTO Customer (CustomerID, ContactName) VALUES   
                         ('C1', 'Andrew Fuller')  
    
  3. Másold le a következő XSD sémát, és illeszted be a Notepadba. Mentsd 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. Másold le a következő updategram kódot a Notepadba, és elmentsd ConcurrencySampleTemplate.xml-ként ugyanabba a könyvtárba, ahol az előző lépésben létrehozott sémát mented. (Figyeld meg, hogy a LastUpdated időbélyeg értéke az alábbi példádban Ügyfél táblázatban eltér, ezért másold ki a LastUpdated tényleges értékét a táblázatból, és illesztsd be a updategramba.)

    <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. Hozd létre és használd az SQLXML 4.0 Test Scriptet (Sqlxml4test.vbs) a sablon végrehajtásához.

    További információ: SqlXML 4.0-lekérdezések végrehajtása az ADO használatával.

Ez a megfelelő XDR-séma:

<?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>  

Lásd még:

Updategram biztonsági megfontolások (SQLXML 4.0)