Поделиться через


Обработка вопросов конкурентности базы данных в Updategrams (SQLXML 4.0)

Как и другие механизмы обновления базы данных, диаграммы обновления должны иметь дело с одновременными обновлениями данных в многопользовательской среде. В диаграммах обновлений используется элемент управления оптимистичной параллелизмой, который использует сравнение данных поля выбора в качестве моментальных снимков, чтобы гарантировать, что обновленные данные не были изменены другим пользовательским приложением, так как он был считыван из базы данных. Граммы обновления включают эти значения моментального снимка в <блоке> до блока обновлений. Перед обновлением базы данных диаграмма обновления проверяет значения, указанные в <блоке перед> блокировкой значений в настоящее время в базе данных, чтобы убедиться, что обновление является допустимым.

Элемент управления оптимистичным параллелизмом предлагает три уровня защиты в диаграмме обновления: низкий (нет), промежуточный и высокий. Вы можете решить, какой уровень защиты требуется, указав соответствующую диаграмму обновления.

Самый низкий уровень защиты

Этот уровень представляет собой слепое обновление, в котором обновление обрабатывается без ссылки на другие обновления, сделанные с момента последнего чтения базы данных. В таком случае необходимо указать только столбцы первичного ключа в <блоке перед> идентификацией записи и указать обновленные сведения в блоке< после> блока.

Например, новый контактный номер телефона в следующей диаграмме обновления правильно, независимо от того, какой номер телефона был ранее. Обратите внимание, что перед<> блоком указывается только первичный ключевой столбец (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>  

Промежуточный уровень защиты

На этом уровне защиты диаграмма обновления сравнивает текущие значения данных, обновляемые со значениями в столбцах базы данных, чтобы убедиться, что значения не были изменены какой-то другой транзакцией, так как запись считывалась транзакцией.

Этот уровень защиты можно получить, указав столбцы первичного ключа и столбцы, которые вы обновляете в блоке<.>

Например, эта диаграмма обновления изменяет значение в столбце Phone таблицы Person.Contact для контакта с ContactID 1. >Перед< блоком указывается атрибут 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>  

Высокий уровень защиты

Высокий уровень защиты гарантирует, что запись остается той же, так как приложение последнее чтение этой записи (т. е. так как приложение считывает запись, она не была изменена другими транзакциями).

Существует два способа получить высокий уровень защиты от одновременных обновлений:

  • Укажите дополнительные столбцы в таблице перед> блоком<.

    При указании дополнительных столбцов в блоке<> до этого диаграмма обновления сравнивает значения, указанные для этих столбцов, со значениями, которые были в базе данных перед применением обновления. Если любой из столбцов записей изменился после того, как транзакция считывает запись, она не выполняет обновление.

    Например, следующая диаграмма обновления обновляет имя смены, но указывает дополнительные столбцы (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> блоке можно просто указать столбец метки времени (если таблица имеет один) вместе с столбцами первичного ключа в блоке перед> блоком<. База данных обновляет столбец метки времени на уникальное значение после каждого обновления записи. В этом случае диаграмма обновления сравнивает значение метки времени с соответствующим значением в базе данных. Значение метки времени, хранящееся в базе данных, является двоичным значением. Поэтому столбец метки времени должен быть указан в схеме как dt:type="bin.hex", dt:type="bin.base64"или sql:datatype="timestamp". (Можно указать тип xml данных или тип данных Microsoft SQL Server.)

Тестирование диаграммы обновления

  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. Скопируйте следующий код диаграммы обновления в Блокнот и сохраните его как 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>  
    
  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>  

См. также

Вопросы безопасности системы обновления (SQLXML 4.0)