Partilhar via


Gestão de Problemas de Concorrência de Bases de Dados em Updategrams (SQLXML 4.0)

Aplica-se a:SQL ServerBanco de Dados SQL do Azure

Tal como outros mecanismos de atualização de bases de dados, os updategrams devem lidar com atualizações simultâneas de dados num ambiente multiutilizador. Os Updategrams utilizam o Controlo de Concorrência Optimista, que utiliza a comparação de dados selecionados de campos como instantâneos para garantir que os dados a atualizar não foram alterados por outra aplicação de utilizador desde que foram lidos da base de dados. Os updategrams incluem estes valores snapshot no <bloco antes> dos updategrams. Antes de atualizar a base de dados, o updategram verifica os valores especificados no <bloco antes> com os valores atualmente presentes na base de dados para garantir que a atualização é válida.

O Controlo de Concorrência Otimista oferece três níveis de proteção num updategram: baixo (nenhum), intermédio e alto. Pode decidir que nível de proteção precisa especificando o updategram em conformidade.

Nível de Proteção Mais Baixo

Este nível é uma atualização cega, na qual a atualização é processada sem referência a outras atualizações feitas desde a última leitura da base de dados. Nesse caso, especifica apenas a(s) coluna(s) principal(es) da chave no <bloco antes> para identificar o registo, e especifica a informação atualizada no <bloco seguinte> .

Por exemplo, o novo número de telefone de contacto no updategram seguinte está correto, independentemente do número anterior. Repare como o bloco< antes> especifica apenas a coluna da chave primária (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>  

Nível Intermédio de Proteção

Neste nível de proteção, o updategram compara o(s) valor(es) atual(s) dos dados a atualizar com o(s) valor(es) na coluna(s) da base de dados para garantir que os valores não foram alterados por outra transação desde que o registo foi lido pela sua transação.

Pode obter este nível de proteção especificando a(s) coluna(s) principal(es) da chave e a(s) coluna(s) que está a atualizar no <bloco before> .

Por exemplo, este updategram altera o valor na coluna Phone da tabela Person.Contact para o contacto com ContactID de 1. O <bloco antes> especifica o atributo Telefone para garantir que este valor de atributo corresponde ao valor na coluna correspondente na base de dados antes de aplicar o valor atualizado.

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

Alto Nível de Proteção

Um elevado nível de proteção garante que o registo se mantém igual desde a última vez que o seu pedido leu esse registo (ou seja, como o seu pedido leu o registo, não foi alterado por nenhuma outra transação).

Existem duas formas de obter este nível elevado de proteção contra atualizações simultâneas:

  • Especifique colunas adicionais na tabela no <bloco de antes> .

    Se especificar colunas adicionais no <bloco before> , o updategram compara os valores especificados para essas colunas com os valores que estavam na base de dados antes de aplicar a atualização. Se alguma das colunas do registo mudou desde que a sua transação leu o registo, o updategram não realiza a atualização.

    Por exemplo, o updategram seguinte atualiza o nome do shift, mas especifica colunas adicionais (StartTime, EndTime) no <bloco before> , solicitando assim um nível superior de proteção contra atualizações concorrentes.

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

    Este exemplo especifica o nível mais elevado de proteção ao especificar todos os valores das colunas para o registo no <bloco anterior> .

  • Especifique a coluna de carimbo temporal (se disponível) no <bloco de antes> .

    Em vez de especificar todas as colunas de registo no <bloco antes> , pode simplesmente especificar a coluna de carimbo temporal (se a tabela tiver uma) juntamente com a(s) coluna(s) de chave primária no <bloco antes> . A base de dados atualiza a coluna de carimbo temporal para um valor único após cada atualização do registo. Neste caso, o updategram compara o valor do carimbo temporal com o valor correspondente na base de dados. O valor de carimbo temporal armazenado na base de dados é um valor binário. Portanto, a coluna de carimbo temporal deve ser especificada no esquema como dt:type="bin.hex",dt:type="bin.base64" ou sql:datatype="timestamp". (Pode especificar tanto o tipo de dado xml como o tipo de dado Microsoft SQL Server.)

Para testar o updategram

  1. Crie esta tabela na base de dados tempdb :

    USE tempdb  
    CREATE TABLE Customer (  
                 CustomerID  varchar(5),  
                 ContactName varchar(20),  
                 LastUpdated timestamp)  
    
  2. Adicione este registo de exemplo:

    INSERT INTO Customer (CustomerID, ContactName) VALUES   
                         ('C1', 'Andrew Fuller')  
    
  3. Copie o seguinte esquema XSD e cole-o no Notepad. Guarda como 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. Copie o seguinte código do updategram para o Notepad e guarde-o como ConcurrencySampleTemplate.xml no mesmo diretório onde guardou o esquema criado no passo anterior. (Note que o valor de carimbo temporal abaixo para o LastUpdated será diferente na sua tabela de exemplo de Clientes, por isso copie o valor real do LastUpdated da tabela e cole no 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. Crie e use o Script de Teste SQLXML 4.0 (Sqlxml4test.vbs) para executar o modelo.

    Para obter mais informações, consulte Usando o ADO para executar consultas SQLXML 4.0.

Este é o esquema XDR equivalente:

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

Ver também

Considerações de segurança do Updategram (SQLXML 4.0)