다음을 통해 공유


Updategram의 데이터베이스 동시성 문제 처리(SQLXML 4.0)

적용 대상: SQL ServerAzure SQL Database

다른 데이터베이스 업데이트 메커니즘과 마찬가지로 updategram은 다중 사용자 환경에서 데이터에 대한 동시 업데이트를 처리해야 합니다. Updategrams는 데이터베이스에서 읽은 이후 업데이트할 데이터가 다른 사용자 애플리케이션에 의해 변경되지 않도록 선택 필드 데이터를 스냅샷으로 비교하는 낙관적 동시성 컨트롤을 사용합니다. Updategram에는 updategram의 이전> 블록에 <이러한 스냅샷 값이 포함됩니다. 데이터베이스를 업데이트하기 전에 updategram은 이전> 블록에 <지정된 값을 현재 데이터베이스의 값에 대해 확인하여 업데이트가 유효한지 확인합니다.

낙관적 동시성 제어는 updategram에서 낮음(없음), 중간 및 높음의 세 가지 보호 수준을 제공합니다. 적절하게 updategram을 지정하여 필요한 보호 수준을 결정할 수 있습니다.

가장 낮은 보호 수준

이 수준은 데이터베이스를 마지막으로 읽은 이후 수행된 다른 업데이트에 대한 참조 없이 업데이트가 처리되는 블라인드 업데이트입니다. 이 경우 이전> 블록에서 기본 키 열<만 지정하여 레코드를 식별하고 이후> 블록에서 <업데이트된 정보를 지정합니다.

예를 들어 다음 updategram의 새 연락처 전화 번호는 이전에 전화 번호가 무엇인지에 관계없이 정확합니다. 이전> 블록이 <기본 키 열(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은 업데이트되는 데이터의 현재 값을 데이터베이스 열의 값과 비교하여 트랜잭션에서 레코드를 읽은 이후 다른 트랜잭션에서 값이 변경되지 않았는지 확인합니다.

이전> 블록에서 <업데이트하는 기본 키 열과 열을 지정하여 이 수준의 보호를 받을 수 있습니다.

예를 들어 이 updategram은 ContactID와의 연락처에 대한 Person.Contact 테이블의 Phone 열 값을 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>  

높은 수준의 보호

보호 수준이 높으면 애플리케이션에서 해당 레코드를 마지막으로 읽은 이후 레코드가 동일하게 유지됩니다(즉, 애플리케이션이 레코드를 읽었기 때문에 다른 트랜잭션에 의해 변경되지 않음).

다음과 같은 두 가지 방법으로 동시 업데이트에 대해 이와 같은 높은 수준의 보호를 사용할 수 있습니다.

  • 이전> 블록의 테이블에 <추가 열을 지정합니다.

    이전> 블록에 <추가 열을 지정하는 경우 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>  
    

    다음은 이전> 블록의 레코드<에 대한 모든 열 값을 지정하여 가장 높은 수준의 보호를 지정하는 예제입니다.

  • 이전> 블록에서 타임스탬프 열(사용 가능한 경우)을 <지정합니다.

    이전> 블록의< 모든 레코드 열을 지정하는 대신 테이블의 타임스탬프 열과 이전> 블록의 <기본 키 열만 지정할 수 있습니다. 데이터베이스는 레코드를 업데이트할 때마다 타임스탬프 열을 고유한 값으로 업데이트합니다. 이 경우 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)