處理 Updategram 中的資料庫並行問題 (SQLXML 4.0)

適用於:SQL ServerAzure SQL 資料庫

與其他資料庫更新機制一樣,Updategram 必須處理多用戶環境中數據的並行更新。 Updategram 會使用開放式並行控制,它會使用選取欄位數據的比較作為快照集,以確保從資料庫讀取數據之後,要更新的數據尚未由另一個使用者應用程式改變。 Updategram 會在 updategram 的前>一個區塊中包含<這些快照集值。 更新資料庫之前,updategram 會根據資料庫中目前的值,檢查 之前> 區塊中指定的<值,以確保更新有效。

開放式並行控制在Updategram中提供三種層級的保護:低(無)、中繼和高。 您可以藉由據此指定 Updategram 來決定您需要的保護層級。

最低層級的保護

此層級是盲目更新,會在其中處理更新,而不會參考自上次讀取資料庫以來所做的其他更新。 在這種情況下,您只會在 前>區塊中<指定主鍵數據行來識別記錄,並在後>區塊中<指定更新的資訊。

例如,下列 updategram 中的新聯繫人電話號碼是正確的,不論先前的電話號碼為何。 請注意,before> 區塊如何<只指定主鍵數據行 (ContactID)。

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

中繼層級的保護

在這個保護層級中,updategram 會比較資料庫數據行中要更新之值的目前值(s),以確保自交易讀取記錄以來,其他交易尚未變更這些值。

您可以指定主要索引鍵數據行和您在前>一個區塊中<更新的數據行,以取得此層級的保護。

例如,這個 Updategram 會變更 Person.Contact 數據表中 ContactID 為 1 之聯繫人的 Phone 數據行中的值。 before <>區塊會指定 Phone 屬性,以確保這個屬性值符合資料庫中對應數據行中的值,然後再套用更新的值。

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

高階保護

高階的保護可確保記錄在應用程式上次讀取該記錄之後維持不變(也就是說,因為您的應用程式已讀取記錄,任何其他交易都不會變更記錄)。

有兩種方式可以針對並行更新取得此高階保護:

  • 在前>區塊的 數據表中<指定其他數據行。

    如果您在 before> 區塊中<指定其他資料行,updategram 會比較針對這些數據行指定的值與套用更新之前資料庫中的值。 如果您的交易讀取記錄之後,任何記錄數據行都已變更,updategram 不會執行更新。

    例如,下列 Updategram 會更新班次名稱,但會在前>一個區塊中<指定其他數據行 (StartTime,EndTime),藉此要求對並行更新提供較高層級的保護。

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

    這個範例會指定前一個區塊中<>記錄的所有數據行值,以指定最高層級的保護。

  • 指定前>區塊中的<時間戳數據列(如果有的話)。

    除了指定 before 區塊中的所有<記錄資料行之外,您可以只指定時間戳數據行(如果數據表有一個),以及前>一個區塊中的<主鍵數據行。> 資料庫會在每個記錄更新之後,將時間戳數據行更新為唯一值。 在此情況下,updategram 會比較時間戳的值與資料庫中對應的值。 儲存在資料庫中的時間戳值是二進位值。 因此,時間戳數據行必須在架構中指定為 dt:type=“bin.hex”dt:type=“bin.base64”sql:datatype=“timestamp”。 (您可以指定 xml 資料類型或 Microsoft SQL Server 資料類型。

測試 updategram

  1. 在 tempdb 資料庫中建立此資料表:

    USE tempdb  
    CREATE TABLE Customer (  
                 CustomerID  varchar(5),  
                 ContactName varchar(20),  
                 LastUpdated timestamp)  
    
  2. 新增此範例記錄:

    INSERT INTO Customer (CustomerID, ContactName) VALUES   
                         ('C1', 'Andrew Fuller')  
    
  3. 複製下列 XSD 架構,並將它貼到 [記事本]。 將它儲存為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. 將下列 Updategram 程式代碼複製到記事本,並將它儲存為ConcurrencySampleTemplate.xml儲存在上一個步驟中建立的架構所在的相同目錄中。 (請注意,LastUpdated 下方的時間戳值在範例 Customer 數據表中會有所不同,因此請從數據表複製 LastUpdated 的實際值,並將其貼到 updategram 中。

    <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. 建立並使用 SQLXML 4.0 測試腳本 (Sqlxml4test.vbs) 來執行範本。

    如需詳細資訊,請參閱使用 ADO 執行 SQLXML 4.0 查詢

這是對等的 XDR 架構:

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

另請參閱

Updategram 安全性考慮 (SQLXML 4.0)