Compartir a través de


Introducción sobre las transacciones de base de datos elástica con Base de datos SQL de Azure

Se aplica a:Azure SQL DatabaseAzure SQL Managed Instance

En este artículo se describe el uso de transacciones de bases de datos elásticas que permiten ejecutar transacciones distribuidas entre bases de datos en la nube para Azure SQL Database y Azure SQL Managed Instance.

En este artículo, los términos "transacciones distribuidas" y "transacciones de base de datos elástica" se consideran sinónimos y se usan indistintamente.

Nota:

También puede usar el Coordinador de transacciones distribuidas (DTC) para Azure SQL Managed Instance para ejecutar transacciones distribuidas en entornos mixtos.

Información general

Las transacciones de base de datos elástica de Azure SQL Database y Azure SQL Managed Instance permiten ejecutar transacciones que abarcan varias bases de datos. Las transacciones de base de datos elástica están disponibles para aplicaciones .NET con ADO.NET y se integran con la conocida experiencia de programación en la que se emplean las clases System.Transaction. Para obtener la biblioteca, vea .NET Framework 4.6.1 (instalador web).

Además, las transacciones distribuidas de instancia administrada de SQL están disponibles en Transact-SQL.

De forma local, este escenario suele requerir la ejecución del Coordinador de transacciones distribuidas de Microsoft (MSDTC). Puesto que el Coordinador de transacciones distribuidas no está disponible en Azure SQL Database, la capacidad de coordinar transacciones distribuidas se integra directamente en SQL Database y SQL Managed Instance. Sin embargo, para SQL Managed Instance, también puede usar el Coordinador de transacciones distribuidas (DTC) para Azure SQL Managed Instance para ejecutar transacciones distribuidas en varios entornos mixtos, como entre instancias administradas, servidores SQL Server, otros sistemas de administración de bases de datos relacionales (RDBMS), aplicaciones personalizadas y otros participantes de transacciones hospedados en cualquier entorno que pueda establecer conectividad de red a Azure.

Las aplicaciones pueden conectarse a cualquier base de datos para iniciar transacciones distribuidas, y una de las bases de datos o de los servidores coordina de forma transparente la transacción distribuida, como se muestra en la ilustración siguiente.

Diagrama de transacciones distribuidas con Azure SQL Database mediante transacciones de bases de datos elásticas.

Escenarios frecuentes

Las transacciones de base de datos elástica permiten a las aplicaciones realizar cambios atómicos en los datos almacenados en varias bases de datos diferentes. Tanto SQL Database como SQL Managed Instance admiten experiencias de desarrollo del lado del cliente en C# y .NET. La experiencia del servidor (código escrito en procedimientos almacenados o scripts del servidor) mediante Transact-SQL solo está disponible para SQL Managed Instance.

Importante

No se admite la ejecución de transacciones de base de datos elástica entre Azure SQL Database y Azure SQL Managed Instance. La transacción de bases de datos elástica solo puede abarcar un conjunto de bases de SQL Database o un conjunto de bases de datos entre instancias administradas.

Las transacciones de base de datos elástica están orientadas a los siguientes escenarios:

  • Aplicaciones de varias bases de datos en Azure: con este escenario, los datos se particionan verticalmente entre varias bases de datos de SQL Database o SQL Managed Instance, de forma que diferentes clases de datos residen en diferentes bases de datos. Algunas operaciones requieren cambios en los datos que se mantienen en dos o más bases de datos. La aplicación emplea transacciones de base de datos elástica para coordinar los cambios entre las bases de datos y garantizar la atomicidad.
  • Aplicaciones de base de datos particionada en Azure: con este escenario, la capa de datos usa la biblioteca cliente de base de datos elástica o el particionamiento automático para particionar horizontalmente los datos entre muchas bases de datos en SQL Database o SQL Managed Instance. Un caso destacado de uso es cuando existe la necesidad de realizar cambios atómicos en una aplicación particionada multiempresa cuando los cambios abarcan a los inquilinos. Piense por ejemplo en una transferencia desde un inquilino a otro, donde cada uno reside en una base de datos diferente. Un segundo caso es el particionamiento específico para satisfacer las necesidades de capacidad de un inquilino de gran tamaño, lo que a su vez supone normalmente que algunas operaciones atómicas deban extenderse entre varias bases de datos usadas para el mismo inquilino. Un tercer caso es el de las actualizaciones atómicas para hacer referencia a los datos que se replican entre bases de datos. Ahora se pueden coordinar operaciones de transacciones atómicas a lo largo de estas líneas entre varias bases de datos. Las transacciones de base de datos elástica usan la confirmación en dos fases para garantizar la atomicidad de las transacciones entre bases de datos. Esto resulta adecuado para transacciones que suponen menos de 100 bases de datos a la vez en una única transacción. Aunque estos límites no se aplican, se supone que las tasas de rendimiento y éxito de las transacciones de base de datos elástica se verán afectadas cuando se excedan estos límites.

Instalación y migración

Las capacidades de las transacciones de base de datos elástica se proporcionan por medio de actualizaciones de las bibliotecas .NET System.Data.dll y System.Transactions.dll. Los archivos DLL garantizan que la confirmación en dos fases se usa cuando es necesario para asegurar la atomicidad. Para empezar a desarrollar aplicaciones mediante transacciones de base de datos elástica, instale .NET Framework 4.6.1 o versión posterior. Cuando se ejecutan en una versión anterior de .NET Framework, las transacciones no podrán promoverse a una transacción distribuida y se producirá una excepción.

Tras la instalación, puede usar las API de transacciones distribuidas de System.Transactions con conexiones a SQL Database y SQL Managed Instance. Si tiene aplicaciones de MSDTC existentes que usan estas API, recompílelas para .NET 4.6 después de instalar Framework 4.6.1. Si los proyectos se destinan a .NET 4.6, usan automáticamente los archivos DLL actualizados de la nueva versión de Framework, y las llamadas API de transacciones distribuidas en combinación con las conexiones a SQL Database o SQL Managed Instance ahora se realizan correctamente.

Recuerde que las transacciones de base de datos elástica no precisan la instalación de MSDTC. Por el contrario, se administran directamente mediante y dentro del servicio. Con ello se simplifican enormemente los escenarios de nube, ya que no es necesario implementar MSDTC para usar transacciones distribuidas con SQL Database o SQL Managed Instance. En la sección 4 se explica con más detalle cómo implementar transacciones de base de datos elástica y la versión de .NET Framework necesaria junto con sus aplicaciones de nube en Azure.

Instalación de .NET para Azure Cloud Services

Azure proporciona varias ofertas para hospedar aplicaciones. NET. Hay disponible una comparación de las diferentes ofertas en Comparación de Azure App Service, Cloud Services y Virtual Machines. Si el SO invitado de la oferta es inferior a .NET 4.6.1, que es el que se requiere para las transacciones elásticas, debe actualizar el SO invitado a 4.6.1.

Para Azure App Service, no se admiten las actualizaciones del SO invitado en estos momentos. En el caso de Azure Virtual Machines, solo tiene que iniciar sesión en la máquina virtual y ejecutar el instalador para la última versión de .NET Framework. Para Azure Cloud Services, hay que incluir la instalación de una versión más reciente de .NET en las tareas de inicio de la implementación. Los conceptos y los pasos se documentan en Instalación de .NET en un rol de servicio en la nube.

El instalador de .NET 4.6.1 puede requerir almacenamiento más temporal durante el proceso de arranque en los servicios en la nube de Azure que el instalador para .NET 4.6. Para garantizar una instalación correcta, debe aumentar el almacenamiento temporal para el servicio en la nube de Azure en el archivo ServiceDefinition.csdef en la sección LocalResources y en la configuración del entorno de la tarea de inicio, como se muestra en el ejemplo siguiente:

<LocalResources>
...
    <LocalStorage name="TEMP" sizeInMB="5000" cleanOnRoleRecycle="false" />
    <LocalStorage name="TMP" sizeInMB="5000" cleanOnRoleRecycle="false" />
</LocalResources>
<Startup>
    <Task commandLine="install.cmd" executionContext="elevated" taskType="simple">
        <Environment>
    ...
            <Variable name="TEMP">
                <RoleInstanceValue xpath="/RoleEnvironment/CurrentInstance/LocalResources/LocalResource[@name='TEMP']/@path" />
            </Variable>
            <Variable name="TMP">
                <RoleInstanceValue xpath="/RoleEnvironment/CurrentInstance/LocalResources/LocalResource[@name='TMP']/@path" />
            </Variable>
        </Environment>
    </Task>
</Startup>

Experiencia de desarrollo de .NET

Aplicaciones de varias bases de datos

En el código de ejemplo siguiente se usa la experiencia de programación familiar con .NET System.Transactions. La TransactionScope clase establece una transacción ambiente en .NET. (Una "transacción de ambiente" es aquella que reside en el subproceso actual). Todas las conexiones abiertas dentro de TransactionScope participan en la transacción. Si intervienen bases de datos diferentes, la transacción se eleva automáticamente a transacción distribuida. El resultado de la transacción se controla mediante la configuración del ámbito como completo para indicar una confirmación.

using (var scope = new TransactionScope())
{
    using (var conn1 = new SqlConnection(connStrDb1))
    {
        conn1.Open();
        SqlCommand cmd1 = conn1.CreateCommand();
        cmd1.CommandText = string.Format("insert into T1 values(1)");
        cmd1.ExecuteNonQuery();
    }
    using (var conn2 = new SqlConnection(connStrDb2))
    {
        conn2.Open();
        var cmd2 = conn2.CreateCommand();
        cmd2.CommandText = string.Format("insert into T2 values(2)");
        cmd2.ExecuteNonQuery();
    }
    scope.Complete();
}

Aplicaciones de base de datos particionada

Las transacciones de base de datos elástica de SQL Database y SQL Managed Instance también admiten la coordinación de transacciones distribuidas en las que se usa el método OpenConnectionForKey de la biblioteca cliente de base de datos elástica a fin de abrir conexiones para una capa de datos escalada horizontalmente. Tenga en cuenta los casos en lo que deba garantizar la coherencia de las transacciones para los cambios entre varios valores diferentes de clave de particionamiento. Las conexiones a las particiones que hospedan los diferentes valores de clave de particionamiento se interrumpen mediante OpenConnectionForKey. Por lo general, las conexiones pueden ser a particiones diferentes de forma que, para garantizar las transacciones, se necesita una transacción distribuida.

En el ejemplo de código siguiente se muestra este método. Se supone que una variable llamada shardmap se usa para representar un mapa de particiones de la biblioteca de cliente de base de datos elástica:

using (var scope = new TransactionScope())
{
    using (var conn1 = shardmap.OpenConnectionForKey(tenantId1, credentialsStr))
    {
        SqlCommand cmd1 = conn1.CreateCommand();
        cmd1.CommandText = string.Format("insert into T1 values(1)");
        cmd1.ExecuteNonQuery();
    }
    using (var conn2 = shardmap.OpenConnectionForKey(tenantId2, credentialsStr))
    {
        var cmd2 = conn2.CreateCommand();
        cmd2.CommandText = string.Format("insert into T1 values(2)");
        cmd2.ExecuteNonQuery();
    }
    scope.Complete();
}

Experiencia de desarrollo de Transact-SQL

Las transacciones distribuidas del servidor que usan Transact-SQL solo están disponibles para Azure SQL Managed Instance. La transacción distribuida solo se puede ejecutar entre instancias que pertenezcan al mismo Grupo de confianza del servidor. En este caso, las instancias administradas deben usar un servidor vinculado para hacerse referencia entre sí.

En el siguiente código de Transact-SQL de ejemplo se usa BEGIN DISTRIBUTED TRANSACTION para iniciar la transacción distribuida.

    -- Configure the Linked Server
    -- Add one Azure SQL Managed Instance as Linked Server
    EXEC sp_addlinkedserver
        @server='RemoteServer', -- Linked server name
        @srvproduct='',
        @provider='MSOLEDBSQL', -- Microsoft OLE DB Driver for SQL Server
        @datasrc='managed-instance-server.46e7afd5bc81.database.windows.net' -- SQL Managed Instance endpoint

    -- Add credentials and options to this Linked Server
    EXEC sp_addlinkedsrvlogin
        @rmtsrvname = 'RemoteServer', -- Linked server name
        @useself = 'false',
        @rmtuser = '<login_name>',         -- login
        @rmtpassword = '<secure_password>' -- password

    USE AdventureWorks2022;
    GO
    SET XACT_ABORT ON;
    GO
    BEGIN DISTRIBUTED TRANSACTION;
    -- Delete candidate from local instance.
    DELETE AdventureWorks2022.HumanResources.JobCandidate
        WHERE JobCandidateID = 13;
    -- Delete candidate from remote instance.
    DELETE RemoteServer.AdventureWorks2022.HumanResources.JobCandidate
        WHERE JobCandidateID = 13;
    COMMIT TRANSACTION;
    GO

Combinación de la experiencia de desarrollo de .NET y Transact-SQL

Las aplicaciones .NET que usan las clases System.Transaction pueden combinar la clase TransactionScope con la instrucción de Transact-SQL BEGIN DISTRIBUTED TRANSACTION. En TransactionScope, la transacción interna que ejecuta BEGIN DISTRIBUTED TRANSACTION se promueve explícitamente a transacción distribuida. Además, cuando se abre la segunda instancia de SqlConnection dentro de TransactionScope, esta se promoverá implícitamente a una transacción distribuida. Una vez iniciada la transacción distribuida, todas las solicitudes posteriores de transacciones, tanto si proceden de .NET como de Transact-SQL, se unen a la transacción distribuida primaria. Como consecuencia, todos los ámbitos de transacción anidados iniciados por la instrucción BEGIN terminan en la misma transacción y las instrucciones COMMIT/ROLLBACK tienen el efecto siguiente en el resultado general:

  • La instrucción COMMIT no tiene ningún efecto en el ámbito de la transacción iniciado por la instrucción BEGIN, es decir, no se confirman resultados antes de que se invoque al método Complete() en el objeto TransactionScope. Si el objeto TransactionScope se destruye antes de completarse, se revierten todos los cambios realizados dentro del ámbito.
  • La instrucción ROLLBACK hace que se revierta TransactionScope completamente. Cualquier intento de dar de alta nuevas transacciones en TransactionScope produce un error posteriormente, así como el intento de invocar a Complete() en el objeto TransactionScope.

Este es un ejemplo en el que la transacción se promueve explícitamente a transacción distribuida con Transact-SQL.

using (TransactionScope s = new TransactionScope())
{
    using (SqlConnection conn = new SqlConnection(DB0_ConnectionString)
    {
        conn.Open();

        // Transaction is here promoted to distributed by BEGIN statement
        //
        Helper.ExecuteNonQueryOnOpenConnection(conn, "BEGIN DISTRIBUTED TRAN");
        // ...
    }

    using (SqlConnection conn2 = new SqlConnection(DB1_ConnectionString)
    {
        conn2.Open();
        // ...
    }

    s.Complete();
}

En el ejemplo siguiente se muestra una transacción que se promueve implícitamente a la transacción distribuida una vez que se inició la segunda instancia de SqlConnection en TransactionScope.

using (TransactionScope s = new TransactionScope())
{
    using (SqlConnection conn = new SqlConnection(DB0_ConnectionString)
    {
        conn.Open();
        // ...
    }

    using (SqlConnection conn = new SqlConnection(DB1_ConnectionString)
    {
        // Because this is second SqlConnection within TransactionScope transaction is here implicitly promoted distributed.
        //
        conn.Open(); 
        Helper.ExecuteNonQueryOnOpenConnection(conn, "BEGIN DISTRIBUTED TRAN");
        Helper.ExecuteNonQueryOnOpenConnection(conn, lsQuery);
        // ...
    }

    s.Complete();
}

Transacciones para SQL Database

Se admiten transacciones de la base de datos elástica entre diferentes servidores en Azure SQL Database. Cuando las transacciones cruzan los límites del servidor, los servidores implicados en primer lugar deben involucrarse en una relación de comunicación mutua. Una vez que se ha establecido la relación de comunicación, cualquier base de datos ubicada en uno de los dos servidores puede participar en transacciones elásticas con bases de datos desde el otro servidor. En el caso de las transacciones distribuidas en más de dos servidores, debe existir una relación de comunicación para cualquier par de servidores.

Use los siguientes cmdlets de PowerShell para administrar las relaciones de comunicación entre los servidores para las transacciones de la base de datos elástica:

  • New-AzSqlServerCommunicationLink: use este cmdlet para crear una nueva relación de comunicación entre dos servidores en Azure SQL Database. La relación es simétrica, lo que significa que ambos servidores pueden iniciar transacciones con el otro servidor.
  • Get-AzSqlServerCommunicationLink: use este cmdlet para recuperar las relaciones de comunicación existentes y sus propiedades.
  • Remove-AzSqlServerCommunicationLink: use este cmdlet para quitar una relación de comunicación existente.

Transacciones para SQL Managed Instance

Las transacciones distribuidas se admiten entre bases de datos dentro de varias instancias. Cuando las transacciones cruzan los límites de las instancias administradas, las instancias participantes deben estar en una relación de comunicación y seguridad mutua. Esto se hace mediante la creación de un grupo de confianza del servidor, operación que se puede realizar mediante Azure Portal, Azure PowerShell o la CLI de Azure. Si las instancias no están en la misma red virtual, es necesario configurar el emparejamiento de red virtual y las reglas de entrada y salida del grupo de seguridad de red deben permitir los puertos 5024 y 11000-12000 en todas las redes virtuales que participan.

Captura de pantalla de los grupos de confianza de SQL en Azure SQL Managed Instance en Azure Portal.

En el diagrama siguiente se muestra el grupo de confianza del servidor con instancias administradas que pueden ejecutar transacciones distribuidas con .NET o Transact-SQL:

Diagrama de transacciones distribuidas con Azure SQL Managed Instance mediante transacciones elásticas.

Supervisión del estado de la transacción

Use vistas de administración dinámica (DMV) para supervisar el estado y el progreso de las transacciones en curso de base de datos elástica. Todas las DMV relacionadas con las transacciones son pertinentes para las transacciones distribuidas en SQL Database y SQL Managed Instance. Puede encontrar la lista correspondiente de DMV aquí: Funciones y vistas de administración dinámica relacionadas con transacciones (Transact-SQL).

Estas DMV son especialmente útiles:

  • sys.dm_tran_active_transactions: enumera las transacciones activas actualmente y su estado. La columna UOW (unidad de trabajo) puede identificar las distintas transacciones secundarias que pertenecen a la misma transacción distribuida. Todas las transacciones de la misma transacción distribuida llevan el mismo valor de UOW. Para obtener más información, vea sys.dm_tran_active_transactions (Transact-SQL).
  • sys.dm_tran_database_transactions: proporciona información adicional sobre las transacciones, como la colocación de la transacción en el registro. Para más información, consulte sys.dm_tran_database_transactions (Transact-SQL).
  • sys.dm_tran_locks: ofrece información sobre los bloqueos actuales de las transacciones. Para obtener más información, vea sys.dm_tran_locks (Transact-SQL).

Limitaciones

Las limitaciones siguientes se aplican actualmente a las transacciones de base de datos elásticas en Azure SQL Database:

  • Se admiten únicamente transacciones entre bases de datos en SQL Database. Otros proveedores de recursos y bases de datos de X/Open XA externos a SQL Database no podrán participar en transacciones de base de datos elástica. Esto significa que dichas transacciones no pueden extenderse entre bases de datos locales de SQL Server y Azure SQL Database. Para las transacciones distribuidas en el entorno local, siga usando MSDTC.
  • Solo se admiten transacciones coordinadas por el cliente desde una aplicación .NET. Está prevista la compatibilidad en el lado servidor con T-SQL, por ejemplo, BEGIN DISTRIBUTED TRANSACTION, pero aún no se encuentra disponible.
  • No se admiten las transacciones por los servicios WCF. Por ejemplo, tiene un método de servicio de WCF que se ejecuta una transacción. Si se encierra la llamada dentro de un ámbito de transacción, se producirá un error como System.ServiceModel.ProtocolException.

Las siguientes limitaciones se aplican actualmente a las transacciones distribuidas (también conocidas como transacciones elásticas o transacciones distribuidas admitidas de forma nativa) en Azure SQL Managed Instance:

  • Con esta tecnología se admiten únicamente transacciones en bases de datos de las instancias administradas. Para todos los demás escenarios que pueden incluir proveedores de recursos y bases de datos X/Open XA fuera de la Instancia Administrada de Azure SQL, debe configurar el Coordinador de Transacciones Distribuidas (DTC) para la Instancia Administrada de Azure SQL.
  • No se admiten las transacciones por los servicios WCF. Por ejemplo, tiene un método de servicio de WCF que se ejecuta una transacción. Si se encierra la llamada dentro de un ámbito de transacción, se producirá un error como System.ServiceModel.ProtocolException.
  • Azure SQL Managed Instance debe formar parte de una configuración de confianza entre instancias con el grupo de confianza de servidor (Azure SQL Managed Instance) para participar en la transacción distribuida.
  • Las limitaciones de Configuración de la confianza entre instancias con el grupo de confianza de servidor (Instancia administrada de Azure SQL) afectan a las transacciones distribuidas.
  • Las instancias administradas que participan en transacciones distribuidas deben tener conectividad a través de puntos de conexión privados (utilizando la dirección IP privada de la red virtual donde se implementan) y deben hacerse referencia mutuamente mediante nombres de dominio totalmente calificados (FQDN). Las aplicaciones cliente pueden usar transacciones distribuidas en puntos de conexión privados. Además, en aquellos casos en los que Transact-SQL aproveche los servidores vinculados que hacen referencia a puntos de conexión privados, las aplicaciones cliente también pueden usar las transacciones distribuidas en puntos de conexión públicos. Dicha limitación se explica en el siguiente diagrama.

Diagrama de una red de conectividad de punto de conexión privado y limitaciones.