處理 Updategram 中的資料庫並行問題 (SQLXML 4.0)
與其他資料庫更新機制一樣,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
在 tempdb 資料庫中建立此資料表:
USE tempdb CREATE TABLE Customer ( CustomerID varchar(5), ContactName varchar(20), LastUpdated timestamp)
新增此範例記錄:
INSERT INTO Customer (CustomerID, ContactName) VALUES ('C1', 'Andrew Fuller')
複製下列 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>
將下列 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>
建立並使用 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>