Share via


Utilisation de transactions avec des sessions SOAP

Cette fonctionnalité sera supprimée dans une prochaine version de Microsoft SQL Server. Évitez d'utiliser cette fonctionnalité dans de nouveaux travaux de développement et prévoyez de modifier les applications qui utilisent actuellement cette fonctionnalité.

Une transaction se compose souvent d'une série de traitements envoyés en chaîne et qui doivent être exécutés dans un certain ordre. Si un des traitements de la transaction n'a pas été exécuté, la transaction peut être restaurée. Dans ce cas, les modifications apportées par les traitements précédents sont restaurées et les données de départ concernées sont rétablies.

Si l'accès aux données SQL se fait selon la méthode traditionnelle, la gestion des traitements d'une transaction au fur et à mesure de leur traitement et de leur exécution repose sur la connexion réseau sous-jacente. Voici un exemple de la relation entre une connexion SQL Server et trois transactions différentes :

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

Notez que les transactions (1) et (3) exécutent, sont contenues et validées au sein du même traitement, tandis que la transaction (2) est répartie sur les traitements (2) et (3). La connexion sous-jacente fournit le contexte qui va garantir que la transaction exécute tous les traitements dans l'ordre voulu. Avec un accès HTTP de type SOAP, le traitement de la transaction ne peut pas être réalisé dans le contexte d'une connexion réseau sous-jacente unique. Par conséquent, pour prendre en charge le traitement de transactions à plusieurs traitements, une session SOAP est nécessaire. L'exemple de code suivant illustre la manière dont les mêmes traitements et transactions que tout à l'heure s'exécuteront avec un accès HTTP de type SOAP.

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

Tant que la même session SOAP (1) reste active, chaque traitement peut être exécuté dans des paires demande/réponse SOAP séparées en l'utilisant comme contexte sous-jacent.

Description de la manière dont SQL Server gère les transactions basées sur le protocole SOAP

Lorsqu'un état de transaction change, des transactions SQL sont initiées au niveau de l'instance de SQL Server. Ceci peut être dû à un des événements suivants, déclenchés lorsque le serveur traite une demande SOAP émanant d'un client :

  • Begin Transaction

  • Commit Transaction

  • Rollback Transaction

  • DTC Enlist in Transaction

  • DTC Defect from Transaction

Par défaut, le serveur travaille en mode de transaction autocommit. Ce comportement suppose un rapport assez simple d'un traitement par transaction et ne retourne pas d'informations concernant la transaction (en-têtes, descripteurs) au client.

Dans l'exemple précédent, le mode de transaction autocommit pourrait suffire pour les transactions (1) et (3). En revanche, la transaction (2) a besoin de plusieurs traitements et exige par conséquent une gestion manuelle.

Gestion manuelle des transactions

Pour gérer manuellement la validation et la restauration des transactions, le client SOAP doit définir l'option sqloptions:environmentChangeNotification avant d'initier la session SOAP, et dans cet en-tête, attribuer à son attribut transactionBoundary la valeur true, comme illustré dans l'exemple de message de demande SOAP suivant :

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

Ceci informe le serveur qu'il doit désactiver le mode de transaction autocommit pour la session en cours. Le serveur envoie ensuite une réponse SOAP (voir l'exemple ci-dessous) qui contient un identificateur de session (jGqn3/X73EGHjFxZ12zovw==), une valeur SqlTransaction confirmant le déclenchement d'un événement BEGIN TRANSACTION sur le serveur et un descripteur de transaction (AQAAADMAAAA=) à utiliser dans toutes les demandes ultérieures qui font partie de la même transaction.

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

Le client peut ensuite joindre manuellement la transaction dans les demandes SOAP suivantes en utilisant l'ID de session et le descripteur transactionnel retourné par le serveur dans la réponse précédente. Cela est illustré dans l'exemple suivant.

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

Une demande SOAP peut joindre une transaction de manière explicite uniquement si le traitement s'exécute dans la session SOAP d'origine de la transaction. Si ce n'est pas le cas, une erreur SOAP est retournée si l'une des conditions suivantes est remplie :

  • Un ID de session SOAP différent est spécifié.

  • L'ID de session SOAP n'est pas spécifié.

  • Le descripteur de transaction n'est pas valide pour la session SOAP en cours.

Une seule transaction à la fois peut être utilisée dans l'attribut transactionDescriptor pour les en-têtes sqlSession. Pour créer des transactions indépendantes multiples dans une même session, vous pouvez vous enregistrer dans la session au moyen de l'en-tête sqlSession sans spécifier l'attribut transactionDescriptor. Remarque : cette méthode implique que l'application cliente tienne un relevé des différentes valeurs de l'attribut transactionDescriptor. Lorsque plusieurs transactions indépendantes sont actives dans la même session, la jointure d'une transaction se fait de la même manière : il suffit de spécifier l'attribut transactionDescriptor dans l'en-tête sqlSession d'une demande SOAP.

Notes

Pour déterminer le niveau des transactions imbriquées actives, vous pouvez lire et utiliser la valeur de la fonction Transact-SQL@@TRANCOUNT.

Schéma XSD pour sqlTransaction

Le code ci-dessous représente le schéma XSD pour l'en-tête sqlTransaction utilisé dans les messages 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>

Le type XSI pour une transaction SQL est xsi:type="typesNs:SqlTransaction", où typesNs est lié à l'espace de noms https://schemas.microsoft.com/sqlserver/2004/SOAP/types/SqlTransaction.