Usar transacciones con sesiones SOAP
Una transacción suele estar formada por una serie de lotes enviados de forma consecutiva y que requieren una ejecución ordenada. Si no se completa un lote de la transacción, se podrá revertir la transacción, deshaciendo los cambios realizados por lotes anteriores en el ámbito de la transacción y restaurando los datos afectados a su estado anterior.
En el acceso habitual a los datos de SQL, se confía en la conexión de red subyacente para dar servicio a todos los lotes de una transacción con varios lotes cuando se procesa y ejecuta. Por ejemplo, puede considerar el caso siguiente como un ejemplo de la relación entre una conexión de SQL Server y tres transacciones distintas:
SQL connection(1)
--> SQL batch(1)
--> transaction(1)
--> SQL batch(2)
--> transaction(2a)
--> SQL batch(3)
--> transaction(2b), transaction(3)
Tenga en cuenta que las transacciones (1)
y (3)
ejecutan el mismo lote y están incluidas y confirmadas en el mismo; sin embargo, la transacción (2)
se extiende a los lotes (2)
y (3)
. La conexión subyacente proporciona el contexto necesario para asegurarse de que la transacción ejecuta todos los lotes en el orden necesario. Con el acceso HTTP SOAP, no se podrá realizar el procesamiento de transacciones en el contexto de una sola conexión de red subyacente. Por lo tanto, para admitir el procesamiento de transacciones con varios lotes, una sola sesión SOAP servirá para el mismo fin. Por ejemplo, en el código siguiente se muestra cómo se puede ejecutar el mismo patrón de lotes y transacciones con acceso HTTP SOAP.
SOAP session(1)
--> SQL batch(1)
--> transaction(1)
--> SQL batch(2)
--> transaction(2a)
--> SQL batch(3)
--> transaction(2b), transaction(3)
Mientras la misma sesión SOAP (1)
permanezca activa, se podrá ejecutar cada lote en pares de mensajes de solicitud y respuesta SOAP independientes utilizándolo como el contexto subyacente.
Administración de las transacciones basada en SOAP en SQL Server 2005
Las transacciones SQL se inician con la instancia de SQL Server 2005 cuando cambia el estado de una transacción. Esto puede estar causado por cualquiera de los siguientes eventos que tienen lugar porque el servidor procesa una solicitud SOAP desde un cliente:
- Begin Transaction
- Commit Transaction
- Rollback Transaction
- DTC Enlist in Transaction
- DTC Defect from Transaction
De forma predeterminada, el servidor funciona en el modo de transacciones con confirmación automática. Este comportamiento da por supuesta una relación bastante simple de uno a uno, de lote a transacción, y no devuelve al cliente ninguna información sobre la transacción (encabezados o descriptores).
El modo de transacción con confirmación automática puede resultar suficiente para las transacciones (1)
y (3)
del ejemplo anterior. Sin embargo, la transacción (2)
del ejemplo requiere más de un lote y, por lo tanto, requiere su administración manual.
Administración manual de las transacciones
Para administrar manualmente las operaciones de confirmar o revertir transacciones, el cliente SOAP debe configurar la opción sqloptions:environmentChangeNotification antes de iniciar la sesión SOAP, y establecer en ese encabezado el valor de su atributo transactionBoundary
como true
, tal como se muestra en el siguiente ejemplo de mensaje de solicitud 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>
Indica al servidor que se deshabilite para el modo de transacción con confirmación automática en la sesión actual. A continuación, el servidor enviará una respuesta SOAP similar a la siguiente, en la que se identificará la sesión (jGqn3/X73EGHjFxZ12zovw==
) y se devolverá un valor SqlTransaction
que confirmará un evento BEGIN TRANSACTION en el servidor y un descriptor de transacción (AQAAADMAAAA=
) para el cliente que se utilizará en las solicitudes SOAP posteriores que formarán parte de la misma transacción.
<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>
A continuación, el cliente podrá combinar manualmente la transacción en las solicitudes SOAP posteriores utilizando el mismo Id. de sesión y el mismo descriptor transaccional devueltos por el servidor en la respuesta anterior. Esto se muestra en el ejemplo siguiente.
<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>
Una solicitud SOAP sólo puede combinar explícitamente una transacción si se ejecuta el lote en la misma sesión SOAP en la que se inició la transacción. De lo contrario, se devolverá un error SOAP si se da alguna de las condiciones siguientes:
- Se especifica un Id. de sesión SOAP distinto.
- No se especifica el Id. de sesión SOAP.
- El descriptor de la transacción no es válido para la sesión SOAP actual.
Las transacciones sólo se pueden utilizar de una en una en el atributo transactionDescriptor para los encabezados sqlSession. Para crear varias transacciones independientes en la misma sesión, puede darlas de alta en la sesión mediante el encabezado sqlSession sin especificar el atributo transactionDescriptor. Tenga en cuenta que en este enfoque se considera que la aplicación cliente realiza un seguimiento de los distintos valores de transactionDescriptor. Si hay varias transacciones independientes activas en la misma sesión, no habrá ninguna diferencia al combinar una transacción, bastará con especificar el atributo transactionDescriptor en el encabezado sqlSession de una solicitud SOAP.
[!NOTA] Para determinar el nivel de transacciones anidadas activas, puede leer y utilizar el valor de la función Transact-SQL @@TRANCOUNT.
Esquema XSD para sqlTransaction
A continuación se muestra el esquema XSD para el encabezado sqlTransaction que se utiliza en los mensajes 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">
(c) Copyright 2004, Microsoft Corporation

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.

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.

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.
</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>
El tipo XSI de una transacción SQL es xsi:type="typesNs:SqlTransaction"
, donde typesNs
está enlazado con el espacio de nombres https://schemas.microsoft.com/sqlserver/2004/SOAP/types/SqlTransaction
.
Vea también
Referencia
Conceptos
Transacciones (motor de la base de datos)