Решение проблем с параллелизмом базы данных в диаграммах обновления (SQLXML 4.0)
Как и другие механизмы обновления базы данных, диаграммы обновления с одновременными обновлениями для данных в многопользовательской среде. В диаграммах обновления используется оптимистическое управление параллелизмом, которое использует сравнение данных в выбранных полях как моментальных снимков, чтобы данные, которые нужно обновить, не были изменены другим пользовательским приложением после чтения из базы данных. Диаграммы обновления включают эти значения моментальных снимков в блок <before> диаграмм обновления. Перед обновление базы данных диаграмма обновления сопоставляет значения, указанные в блоке <before>, с текущими значениями в базе данных, чтобы убедиться в допустимости обновления.
Управление оптимистичным параллелизмом обеспечивает три уровня защиты в диаграмме обновления: низкий (нет), промежуточный и высокий. Можно выбрать нужный уровень защиты, указав соответствующую диаграмму обновления.
Самый нижний уровень защиты
Этот уровень обеспечивает «слепое» обновление, при котором обновление обрабатывается без учета других обновлений, сделанных со времени последнего чтения базы данных. В этих случаях указываются только столбцы первичного ключа в блоке <before>, чтобы идентифицировать запись, и указываются обновленные сведения в блоке <after>.
Например, новый номер телефона для связи в следующей диаграмме обновления верен, независимо от предыдущего значения телефонного номера. Обратите внимание, что блок <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>
Промежуточный уровень защиты
На этом уровне защиты диаграмма обновления сравнивает текущие значения обновляемых данных со значениями в столбцах базы данных, чтобы проверить, что значения не были изменены другой транзакцией после чтения записи данной транзакцией.
Этот уровень защиты можно обеспечить, указав столбцы первичного ключа и обновляемые столбцы в блоке <before>.
Например, данная диаграмма обновления изменяет значение в столбце Phone таблицы Person.Contact для контактного лица со значением ContactID, равным 1. Блок <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>.
Если указаны дополнительные столбцы в блоке <before> , диаграмма обновления сравнивает значения, указанные для этих столбцов, со значениями, которые были в базе данных перед применением обновления. Если какие-нибудь столбцы записи изменились после чтения записи транзакцией, диаграмма обновления не выполняет обновление.
Например, следующая диаграмма обновления обновляет название рабочей смены, но указывает дополнительные столбцы (StartTime,EndTime) в блоке <before>, тем самым запрашивая более высокий уровень защиты от одновременных обновлений.
<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>.
Указать столбец временных меток (если доступен) в блоке <before>.
Вместо указания всех столбцов записи в блоке <before> можно просто указать столбец временных меток (если он есть в таблице) наряду со столбцами первичного ключа в блоке <before>. Если база данных обновляет столбец временных меток до уникального значения после каждого обновления записи. В этом случае диаграмма обновления сравнивает значения временных меток с соответствующим значением в базе данных. Значение временной метки, сохраненное в базе данных, является двоичным значением. Поэтому столбец временных меток в схеме должен быть указан как dt:type="bin.hex", dt:type="bin.base64" или sql:datatype="timestamp". (Можно указать тип данных xml или тип данных MicrosoftSQL Server.)
Тестирование диаграммы обновления
Создайте следующую таблицу в базе данных tempdb.
USE tempdbCREATE 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>Скопируйте следующий код диаграммы обновления в приложении «Блокнот» и сохраните его в файле с именем ConcurrencySampleTemplate.xml в том же каталоге, в котором сохранена схема, созданная на предыдущем шаге. (Обратите внимание, что указанное ниже значение временной метки для LastUpdated будет иным в примере таблицы Customer, поэтому скопируйте фактическое значение для LastUpdated из таблицы и вставьте его в диаграмму обновления.)
<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>