Применение транзакций с сеансами SOAP

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

При обычном доступе к данным с помощью языка SQL на базовое сетевое подключение возлагается задача по обслуживанию всех пакетов транзакции при их обработке и выполнении. Например, рассмотрим связь между соединением SQL Server и тремя различными транзакциями:

SQL connection(1)
     --> SQL batch(1)
          --> transaction(1)
     --> SQL batch(2)
          --> transaction(2a)
     --> SQL batch(3)
          --> transaction(2b), transaction(3)

Следует отметить, что транзакции (1) и (3) выполняются и содержатся внутри одного пакета; транзакция (2) занимает пакеты (2) и (3). Базовое соединение содержит контекст, позволяющий удостовериться в том, что все пакеты в транзакции выполняются в необходимой последовательности. Если доступ осуществляется при помощи протокола HTTP SOAP, обработка транзакции не может производиться с использованием единственного базового сетевого подключения. Поэтому при обработке транзакций, состоящих из нескольких пакетов, используется отдельный сеанс SOAP. С помощью представленного ниже программного кода показано, как та же последовательность пакетов и транзакций будет выполняться при осуществлении доступа с помощью протокола HTTP SOAP.

SOAP session(1)
     --> SQL batch(1)
          --> transaction(1)
     --> SQL batch(2)
          --> transaction(2a)
     --> SQL batch(3)
          --> transaction(2b), transaction(3)

Пока сеанс SOAP (1) активен, каждый пакет может выполняться с помощью отдельных пар сообщений SOAP типа «запрос-ответ», при этом используя их в качестве базового контекста.

Управление транзакциями SOAP в SQL Server 2005

В SQL транзакции исходят от экземпляра SQL Server 2005 при изменении их состояния. Транзакция может быть вызвана одним из следующих событий, происходящих при обработке сервером запроса SOAP:

  • Начать транзакцию
  • Зафиксировать транзакцию
  • Выполнить откат транзакции
  • Прикрепить DTC к транзакции
  • Открепить DTC от транзакции

По умолчанию сервер работает в режиме Автоматическая фиксация транзакций. В указанном режиме используется обычное соотношение пакетов и транзакций «один к одному»; при этом клиенту не предоставляются сведения о транзакциях (их заголовки и дескрипторы).

Режим «Автоматическая фиксация транзакций» может применяться для транзакций (1) и (3) предыдущего примера. Транзакция (2) указанного примера занимает более одного пакета, поэтому ее настройку необходимо производить вручную.

Ручная настройка транзакций

Чтобы вручную настроить выполнение и откат транзакции, клиенту SOAP перед началом сеанса SOAP необходимо установить параметр sqloptions:environmentChangeNotification, затем под этим заголовком установить значение true для атрибута transactionBoundary. Пример кода сообщения запроса SOAP представлен ниже:

<SOAP-ENV:Envelope  xmlns:SOAP-ENV="https://schemas.xmlsoap.org/soap/envelope/"
              xmlns:sql="https://schemas.microsoft.com/sqlserver/2004/SOAP"
              xmlns:xsi="http://www.w3.org/2004/XMLSchema-instance"
              xmlns:sqlparam="https://schemas.microsoft.com/sqlserver/2004/sqltypes/SqlParameter"
              xmlns:sqlsoaptypes="https://schemas.microsoft.com/sqlserver/2004/sqltypes"
              xmlns:sqloptions="https://schemas.microsoft.com/sqlserver/2004/SOAP/Options">
  <SOAP-ENV:Header>
    <sqloptions:environmentChangeNotifications transactionBoundary="true" />
    <sqloptions:sqlSession initiate="true" timeout="60"/>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body>
    <sql:sqlbatch>
      <sql:BatchCommands>
        USE master
        BEGIN TRANSACTION
        CREATE TABLE session_table (col1 int);
      </sql:BatchCommands>
    </sql:sqlbatch>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

В результате отсылки данного сообщения сервер отключает режим «Автоматическая фиксация транзакций» для данного сеанса. При этом сервер отправит ответное сообщение SOAP, пример которого представлен ниже. В данном примере происходит определение сеанса (jGqn3/X73EGHjFxZ12zovw==), а также возвращается значение SqlTransaction, подтверждающее событие «Начать транзакцию» на сервере, и дескриптор транзакции (AQAAADMAAAA=), предназначенный для использования в последующих запросах SOAP, являющихся частями общей транзакции.

<SOAP-ENV:Envelope xml:space="preserve"
                   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                   xmlns:SOAP-ENV="https://schemas.xmlsoap.org/soap/envelope/"
                   xmlns:sql="https://schemas.microsoft.com/sqlserver/2004/SOAP"
                   xmlns:sqlsoaptypes="https://schemas.microsoft.com/sqlserver/2004/SOAP/types"
                   xmlns:sqlrowcount="https://schemas.microsoft.com/sqlserver/2004/SOAP/types/SqlRowCount"                    xmlns:sqlmessage="https://schemas.microsoft.com/sqlserver/2004/SOAP/types/SqlMessage"                    xmlns:sqlresultstream="https://schemas.microsoft.com/sqlserver/2004/SOAP/types/SqlResultStream"                    xmlns:sqltransaction="https://schemas.microsoft.com/sqlserver/2004/SOAP/types/SqlTransaction"                    xmlns:sqltypes="https://schemas.microsoft.com/sqlserver/2004/sqltypes">
  <SOAP-ENV:Header xmlns:sqloptions="https://schemas.microsoft.com/sqlserver/2004/SOAP/Options">
    <sqloptions:sqlSession sessionId="jGqn3/X73EGHjFxZ12zovw==" timeout="1200">
    </sqloptions:sqlSession>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body>
    <sql:sqlbatchResponse>
       <sql:sqlbatchResult>
          <sqlresultstream:SqlTransaction xsi:type="sqltransaction:SqlTransaction">
             <sqltransaction:Descriptor>AQAAADMAAAA=</sqltransaction:Descriptor>
             <sqltransaction:Type>Begin</sqltransaction:Type>
          </sqlresultstream:SqlTransaction>
       </sql:sqlbatchResult>
    </sql:sqlbatchResponse>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

После этого клиент сможет вручную включать транзакцию в последующие запросы SOAP, при этом используя те же самые идентификатор сеанса и дескриптор транзакции, возвращенные в результате предыдущего отклика. Указанные операции показаны в следующем примере.

<SOAP-ENV:Envelope  xmlns:SOAP-ENV="https://schemas.xmlsoap.org/soap/envelope/"
                    xmlns:sql="https://schemas.microsoft.com/sqlserver/2004/SOAP"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:sqlparam="https://schemas.microsoft.com/sqlserver/2004/sqltypes/SqlParameter"
                    xmlns:sqlsoaptypes="https://schemas.microsoft.com/sqlserver/2004/sqltypes"
                    xmlns:sqloptions="https://schemas.microsoft.com/sqlserver/2004/SOAP/Options">
  <SOAP-ENV:Header>
    <sqloptions:sqlSession sessionId="jGqn3/X73EGHjFxZ12zovw==" transactionDescriptor="AQAAADMAAAA="/>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body>
    <sql:sqlbatch>
      <sql:BatchCommands>
        INSERT INTO session_table values (2005)
        COMMIT TRANSACTION
      </sql:BatchCommands>
    </sql:sqlbatch>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

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

  • Задан другой идентификатор сеанса SOAP.
  • Не задан идентификатор сеанса SOAP.
  • Дескриптор транзакции недействителен для текущего сеанса SOAP.

В атрибуте transactionDescriptor заголовков sqlSession одновременно может быть указано не более одной транзакции. Чтобы создать несколько независимых транзакций внутри одного сеанса, необходимо прикрепиться к нему, используя заголовок sqlSession без указания атрибута transactionDescriptor. Заметим, что при этом клиентское приложение отслеживает различные значения атрибута transactionDescriptor. Если в одном сеансе имеется несколько независимых транзакций, то при подключении к ним используется один и тот же синтаксис запроса SOAP, в котором указываются различные значения атрибута transactionDescriptor заголовка sqlSession.

ms189243.note(ru-ru,SQL.90).gifПримечание.
Чтобы определить уровень активных на данный момент вложенных транзакций, используется функция Transact-SQL @@TRANCOUNT.

XSD-схема для заголовка sqlTransaction

Ниже представлена XSD-схема заголовка sqlTransaction, используемая в сообщениях SOAP:

<xsd:schema
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    attributeFormDefault="qualified"
    elementFormDefault="qualified"
    targetNamespace="https://schemas.microsoft.com/sqlserver/2004/SOAP/types/SqlTransaction">
<xsd:annotation><xsd:documentation xml:lang="en">&#xd;&#xa;(c) Copyright 2004, Microsoft Corporation&#xd;&#xa;&#xd;&#xa;The following schema for Microsoft SQL Server is presented in XML format and is for informational purposes only. Microsoft Corporation ("Microsoft") may have trademarks, copyrights, or other intellectual property rights covering subject matter in the schema.&#xd;&#xa;&#xd;&#xa;Microsoft does not make any representation or warranty regarding the schema or any product or item developed based on the schema. The schema is provided to you on an AS IS basis.  Microsoft disclaims all express, implied and statutory warranties, including but not limited to the implied warranties of merchantability, fitness for a particular purpose, and freedom from infringement. Without limiting the generality of the foregoing, Microsoft does not make any warranty of any kind that any item developed based on the schema, or any portion of the schema, will not infringe any copyright, patent, trade secret, or other intellectual property right of any person or entity in any country. It is your responsibility to seek licenses for such intellectual property rights where appropriate.&#xd;&#xa;&#xd;&#xa;MICROSOFT SHALL NOT BE LIABLE FOR ANY DAMAGES OF ANY KIND ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SCHEMA, INCLUDING WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL (INCLUDING ANY LOST PROFITS), PUNITIVE OR SPECIAL DAMAGES, WHETHER OR NOT MICROSOFT HAS BEEN ADVISED OF SUCH DAMAGES.&#xd;&#xa;</xsd:documentation></xsd:annotation>
  <xsd:complexType name="SqlTransaction">
    <xsd:sequence minOccurs="1" maxOccurs="1">
      <xsd:element name="Descriptor" type="xsd:base64Binary" />
      <xsd:element name="Type">
         <xsd:simpleType>
            <xsd:restriction base="xsd:string">
              <xsd:enumeration value="Begin"/>
              <xsd:enumeration value="Commit"/>
              <xsd:enumeration value="Rollback"/>
              <xsd:enumeration value="EnlistDTC"/>
              <xsd:enumeration value="Defect"/>
            </xsd:restriction>
         </xsd:simpleType>
      </xsd:element>
    </xsd:sequence>
  </xsd:complexType>
</xsd:schema>

XSI-тип для транзакции SQL определяется как xsi:type="typesNs:SqlTransaction", где пространство имен typesNs привязано к URI-адресу https://schemas.microsoft.com/sqlserver/2004/SOAP/types/SqlTransaction.

См. также

Справочник

Работа с сеансами SOAP

Основные понятия

Транзакции (компонент Database Engine)

Другие ресурсы

Работа с сеансами SOAP

Справка и поддержка

Получение помощи по SQL Server 2005