Over clouddatabases gedistribueerde transacties

Van toepassing op: Azure SQL DatabaseAzure SQL Managed Instance

In dit artikel wordt beschreven hoe u transacties voor elastische databases gebruikt waarmee u gedistribueerde transacties kunt uitvoeren in clouddatabases voor Azure SQL Database en Azure SQL Managed Instance. In dit artikel worden de termen 'gedistribueerde transacties' en 'transacties voor elastische databases' beschouwd als synoniemen en worden ze door elkaar gebruikt.

Notitie

U kunt ook de gedistribueerde transactiecoördinator voor Azure SQL Managed Instance gebruiken om gedistribueerde transacties uit te voeren in gemengde omgevingen.

Overzicht

Met elastische databasetransacties voor Azure SQL Database en Azure SQL Managed Instance kunt u transacties uitvoeren die meerdere databases omvatten. Transacties voor elastische databases zijn beschikbaar voor .NET-toepassingen die gebruikmaken van ADO.NET en integreren met de vertrouwde programmeerervaring met behulp van de System.Transaction-klassen . Zie .NET Framework 4.6.1 (webinstallatieprogramma) om de bibliotheek op te halen. Daarnaast zijn gedistribueerde transacties voor beheerde exemplaren beschikbaar in Transact-SQL.

On-premises vereist een dergelijk scenario meestal het uitvoeren van Microsoft Distributed Transaction Coordinator (MSDTC). Omdat MSDTC niet beschikbaar is voor Azure SQL Database, is de mogelijkheid om gedistribueerde transacties rechtstreeks te coördineren, geïntegreerd in SQL Database en SQL Managed Instance. Voor SQL Managed Instance kunt u echter ook de gedistribueerde transactiecoördinator gebruiken om gedistribueerde transacties uit te voeren in een aantal gemengde omgevingen, zoals voor beheerde exemplaren, SQL Servers, andere relationele databasebeheersystemen (RDBMs), aangepaste toepassingen en andere transactiedeelnemers die worden gehost in elke omgeving die netwerkconnectiviteit met Azure tot stand kan brengen.

Toepassingen kunnen verbinding maken met elke database om gedistribueerde transacties te starten en een van de databases of servers coördineert de gedistribueerde transactie transparant, zoals wordt weergegeven in de volgende afbeelding.

Distributed transactions with Azure SQL Database using elastic database transactions

Algemene scenario's

Met transacties voor elastische databases kunnen toepassingen atomische wijzigingen aanbrengen in gegevens die zijn opgeslagen in verschillende databases. Zowel SQL Database als SQL Managed Instance bieden ondersteuning voor ontwikkelervaringen aan de clientzijde in C# en .NET. Een ervaring aan de serverzijde (code die is geschreven in opgeslagen procedures of scripts aan de serverzijde) met behulp van Transact-SQL is alleen beschikbaar voor SQL Managed Instance.

Belangrijk

Het uitvoeren van transacties voor elastische databases tussen Azure SQL Database en Azure SQL Managed Instance wordt niet ondersteund. Transactie voor elastische databases kan alleen betrekking hebben op een set databases in SQL Database of een set databases in beheerde exemplaren.

Transacties voor elastische databases zijn gericht op de volgende scenario's:

  • Toepassingen met meerdere databases in Azure: Met dit scenario worden gegevens verticaal gepartitioneerd over verschillende databases in SQL Database of SQL Managed Instance, zodat verschillende soorten gegevens zich in verschillende databases bevinden. Voor sommige bewerkingen zijn wijzigingen in gegevens vereist, die in twee of meer databases worden bewaard. De toepassing maakt gebruik van transacties voor elastische databases om de wijzigingen in databases te coördineren en atomiciteit te garanderen.
  • Shard-databasetoepassingen in Azure: In dit scenario maakt de gegevenslaag gebruik van de elastic database-clientbibliotheek of zelf-sharding om de gegevens horizontaal te partitioneren in veel databases in SQL Database of SQL Managed Instance. Een prominente use case is de noodzaak om atomische wijzigingen uit te voeren voor een shard-toepassing met meerdere tenants wanneer wijzigingen tenants omvatten. Denk bijvoorbeeld aan een overdracht van de ene tenant naar de andere, die beide zich in verschillende databases bevinden. Een tweede geval is fijnmazige sharding om tegemoet te komen aan capaciteitsbehoeften voor een grote tenant, wat op zijn beurt impliceert dat sommige atomische bewerkingen moeten worden uitgerekt over verschillende databases die voor dezelfde tenant worden gebruikt. Een derde geval is atomische updates om te verwijzen naar gegevens die worden gerepliceerd in databases. Atomische, verwerkte bewerkingen op deze regels kunnen nu worden gecoördineerd in verschillende databases. Transacties in elastische databases maken gebruik van twee fasen doorvoeren om transactie atomiciteit tussen databases te garanderen. Het is een goede oplossing voor transacties waarbij minder dan 100 databases tegelijk binnen één transactie zijn betrokken. Deze limieten worden niet afgedwongen, maar u kunt verwachten dat prestaties en slagingspercentages voor elastische databasetransacties lijden wanneer deze limieten worden overschreden.

Installatie en migratie

De mogelijkheden voor transacties voor elastische databases worden aangeboden via updates voor de .NET-bibliotheken System.Data.dll en System.Transactions.dll. De DLL's zorgen ervoor dat doorvoer in twee fasen waar nodig wordt gebruikt om atomiciteit te garanderen. Installeer .NET Framework 4.6.1 of een latere versie om toepassingen te ontwikkelen met behulp van transacties voor elastische databases. Wanneer transacties worden uitgevoerd op een eerdere versie van .NET Framework, mislukken transacties tot een gedistribueerde transactie en wordt er een uitzondering gegenereerd.

Na de installatie kunt u de gedistribueerde transactie-API's in System.Transactions gebruiken met verbindingen met SQL Database en SQL Managed Instance. Als u bestaande MSDTC-toepassingen hebt die gebruikmaken van deze API's, bouwt u uw bestaande toepassingen voor .NET 4.6 opnieuw op nadat u het Framework 4.6.1 hebt geïnstalleerd. Als uw projecten zijn gericht op .NET 4.6, gebruiken ze automatisch de bijgewerkte DLL's uit de nieuwe frameworkversie en gedistribueerde transactie-API-aanroepen in combinatie met verbindingen met SQL Database of SQL Managed Instance.

Houd er rekening mee dat transacties voor elastische databases geen MSDTC hoeven te installeren. In plaats daarvan worden transacties voor elastische databases rechtstreeks beheerd door en binnen de service. Dit vereenvoudigt cloudscenario's aanzienlijk, omdat een implementatie van MSDTC niet nodig is voor het gebruik van gedistribueerde transacties met SQL Database of SQL Managed Instance. In sectie 4 wordt in meer detail uitgelegd hoe u transacties voor elastische databases en het vereiste .NET Framework samen met uw cloudtoepassingen in Azure implementeert.

.NET-installatie voor Azure Cloud Services

Azure biedt verschillende aanbiedingen voor het hosten van .NET-toepassingen. Een vergelijking van de verschillende aanbiedingen is beschikbaar in vergelijking met Azure-app Service, Cloud Services en Virtual Machines. Als het gastbesturingssystem van de aanbieding kleiner is dan .NET 4.6.1 vereist voor elastische transacties, moet u het gastbesturingssystemen upgraden naar 4.6.1.

Voor Azure-app Service worden upgrades naar het gastbesturingssystemen momenteel niet ondersteund. Voor Virtuele Azure-machines meldt u zich aan bij de VIRTUELE machine en voert u het installatieprogramma uit voor het nieuwste .NET Framework. Voor Azure Cloud Services moet u de installatie van een nieuwere .NET-versie opnemen in de opstarttaken van uw implementatie. De concepten en stappen worden beschreven in .NET installeren op een cloudservicerol.

Houd er rekening mee dat het installatieprogramma voor .NET 4.6.1 mogelijk meer tijdelijke opslag vereist tijdens het opstartproces op Azure-cloudservices dan het installatieprogramma voor .NET 4.6. Om een geslaagde installatie te garanderen, moet u de tijdelijke opslag voor uw Azure-cloudservice in uw ServiceDefinition.csdef-bestand in de sectie LocalResources en de omgevingsinstellingen van uw opstarttaak verhogen, zoals wordt weergegeven in het volgende voorbeeld:

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

.NET-ontwikkelervaring

Toepassingen met meerdere databases

De volgende voorbeeldcode maakt gebruik van de vertrouwde programmeerervaring met .NET System.Transactions. De TransactionScope-klasse brengt een omgevingstransactie in .NET tot stand. (Een 'omgevingstransactie' is een transactie die zich in de huidige thread bevindt.) Alle verbindingen die in de TransactionScope zijn geopend, nemen deel aan de transactie. Als verschillende databases deelnemen, wordt de transactie automatisch verhoogd naar een gedistribueerde transactie. Het resultaat van de transactie wordt bepaald door het bereik in te stellen dat moet worden voltooid om een doorvoering aan te geven.

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();
}

Shard-databasetoepassingen

Transacties voor elastische databases voor SQL Database en SQL Managed Instance ondersteunen ook het coördineren van gedistribueerde transacties waarbij u de methode Open Verbinding maken ionForKey van de clientbibliotheek voor elastische databases gebruikt om verbindingen te openen voor een uitgeschaalde gegevenslaag. Overweeg gevallen waarin u transactionele consistentie moet garanderen voor wijzigingen in verschillende sharding-sleutelwaarden. Verbinding maken ies voor de shards die als host fungeren voor de verschillende sharding-sleutelwaarden, worden brokered met behulp van Open Verbinding maken ionForKey. In het algemeen kunnen de verbindingen met verschillende shards zijn, zodat transactionele garanties een gedistribueerde transactie vereisen. Het volgende codevoorbeeld illustreert deze aanpak. Hierbij wordt ervan uitgegaan dat een variabele met de naam shardmap wordt gebruikt om een shard-toewijzing uit de clientbibliotheek van de elastische database weer te geven:

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();
}

Transact-SQL-ontwikkelervaring

Gedistribueerde transacties aan de serverzijde met Behulp van Transact-SQL zijn alleen beschikbaar voor Azure SQL Managed Instance. Gedistribueerde transactie kan alleen worden uitgevoerd tussen exemplaren die deel uitmaken van dezelfde serververtrouwensgroep. In dit scenario moeten beheerde exemplaren een gekoppelde server gebruiken om naar elkaar te verwijzen.

In de volgende Transact-SQL-code wordt GEBRUIKgemaakt van BEGIN DISTRIBUTED TRANSACTION om een gedistribueerde transactie te starten.

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

Combinatie van .NET- en Transact-SQL-ontwikkelervaring

.NET-toepassingen die gebruikmaken van System.Transaction-klassen kunnen TransactionScope-klasse combineren met transact-SQL-instructie BEGIN DISTRIBUTED TRANSACTION. Binnen TransactionScope wordt interne transactie die START DISTRIBUTED TRANSACTION uitvoert, expliciet gepromoveerd naar gedistribueerde transactie. Wanneer de tweede Sql Verbinding maken on wordt geopend binnen de TransactionScope, wordt deze ook impliciet gepromoveerd naar gedistribueerde transacties. Zodra de gedistribueerde transactie is gestart, worden alle volgende transactieaanvragen, ongeacht of deze afkomstig zijn van .NET of Transact-SQL, lid van de bovenliggende gedistribueerde transactie. Als gevolg hiervan komen alle geneste transactiebereiken die door de BEGIN-instructie zijn geïnitieerd, in dezelfde transactie terecht en hebben COMMIT/ROLLBACK-instructies het volgende effect op het algehele resultaat:

  • COMMIT-instructie heeft geen effect op het transactiebereik dat is geïnitieerd door de BEGIN-instructie, dat wil zeggen dat er geen resultaten worden doorgevoerd voordat de complete() methode wordt aangeroepen op het TransactionScope-object. Als TransactionScope-object wordt vernietigd voordat het wordt voltooid, worden alle wijzigingen die binnen het bereik worden uitgevoerd, teruggedraaid.
  • RollBACK-instructie zorgt ervoor dat de volledige TransactionScope terugdraait. Pogingen om nieuwe transacties in TransactionScope in te schakelen, mislukken daarna en proberen Complete() aan te roepen op TransactionScope-object.

Hier volgt een voorbeeld waarbij transactie expliciet wordt gepromoveerd naar gedistribueerde transacties met 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();
}

In het volgende voorbeeld ziet u een transactie die impliciet wordt gepromoveerd naar gedistribueerde transactie zodra de tweede Sql Verbinding maken on is gestart in 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();
}

Transacties voor SQL Database

Transacties voor elastische databases worden ondersteund op verschillende servers in Azure SQL Database. Wanneer transacties servergrenzen overschrijden, moeten de deelnemende servers eerst worden ingevoerd in een wederzijdse communicatierelatie. Zodra de communicatierelatie tot stand is gebracht, kan elke database op een van de twee servers deelnemen aan elastische transacties met databases vanaf de andere server. Met transacties die meer dan twee servers omvatten, moet er een communicatierelatie aanwezig zijn voor elk paar servers.

Gebruik de volgende PowerShell-cmdlets voor het beheren van communicatierelaties tussen servers voor transacties in elastische databases:

  • New-AzSqlServerCommunicationLink: gebruik deze cmdlet om een nieuwe communicatierelatie tussen twee servers in Azure SQL Database te maken. De relatie is symmetrisch, wat betekent dat beide servers transacties met de andere server kunnen initiëren.
  • Get-AzSqlServerCommunicationLink: gebruik deze cmdlet om bestaande communicatierelaties en hun eigenschappen op te halen.
  • Remove-AzSqlServerCommunicationLink: gebruik deze cmdlet om een bestaande communicatierelatie te verwijderen.

Transacties voor SQL Managed Instance

Gedistribueerde transacties worden ondersteund in meerdere databases binnen meerdere exemplaren. Wanneer transacties de grenzen van een beheerd exemplaar overschrijden, moeten de deelnemende exemplaren een wederzijdse beveiligings- en communicatierelatie hebben. Dit wordt gedaan door een serververtrouwensgroep te maken, die kan worden gedaan met behulp van Azure Portal of Azure PowerShell of de Azure CLI. Als exemplaren zich niet in hetzelfde virtuele netwerk bevinden, moet u peering van virtuele netwerken en regels voor binnenkomende en uitgaande netwerkbeveiligingsgroepen configureren om poorten 5024 en 11000-12000 toe te staan op alle deelnemende virtuele netwerken.

Server Trust Groups on Azure Portal

In het volgende diagram ziet u een serververtrouwensgroep met beheerde exemplaren die gedistribueerde transacties kunnen uitvoeren met .NET of Transact-SQL:

Distributed transactions with Azure SQL Managed Instance using elastic transactions

Transactiestatus bewaken

Gebruik DMV's (Dynamic Management Views) om de status en voortgang van uw lopende transacties voor elastische databases te bewaken. Alle DMV's met betrekking tot transacties zijn relevant voor gedistribueerde transacties in SQL Database en SQL Managed Instance. Hier vindt u de bijbehorende lijst met DMV's: Transaction Related Dynamic Management Views and Functions (Transact-SQL).

Deze DMV's zijn bijzonder nuttig:

  • sys.dm_tran_active_transactions: bevat momenteel actieve transacties en hun status. De kolom UOW (Unit Of Work) kan de verschillende onderliggende transacties identificeren die deel uitmaken van dezelfde gedistribueerde transactie. Alle transacties binnen dezelfde gedistribueerde transactie hebben dezelfde UOW-waarde. Zie de DMV-documentatie voor meer informatie.
  • sys.dm_tran_database_transactions: biedt aanvullende informatie over transacties, zoals de plaatsing van de transactie in het logboek. Zie de DMV-documentatie voor meer informatie.
  • sys.dm_tran_locks: Bevat informatie over de vergrendelingen die momenteel worden bewaard door lopende transacties. Zie de DMV-documentatie voor meer informatie.

Beperkingen

De volgende beperkingen zijn momenteel van toepassing op transacties voor elastische databases in SQL Database:

  • Alleen transacties tussen databases in SQL Database worden ondersteund. Andere X/Open XA-resourceproviders en -databases buiten SQL Database kunnen niet deelnemen aan transacties voor elastische databases. Dit betekent dat transacties van elastische databases niet kunnen worden uitgerekt over on-premises SQL Server en Azure SQL Database. Voor gedistribueerde transacties on-premises blijft u MSDTC gebruiken.
  • Alleen door clients gecoördineerde transacties vanuit een .NET-toepassing worden ondersteund. Ondersteuning aan de serverzijde voor T-SQL, zoals BEGIN DISTRIBUTED TRANSACTION, is gepland, maar is nog niet beschikbaar.
  • Transacties tussen WCF-services worden niet ondersteund. U hebt bijvoorbeeld een WCF-servicemethode waarmee een transactie wordt uitgevoerd. Het insluiten van de aanroep binnen een transactiebereik mislukt als een System.ServiceModel.ProtocolException.

De volgende beperkingen zijn momenteel van toepassing op gedistribueerde transacties (ook wel elastische transacties of systeemeigen ondersteunde gedistribueerde transacties genoemd) in SQL Managed Instance:

  • Met deze technologie worden alleen transacties tussen databases in beheerde exemplaren ondersteund. Voor alle andere scenario's die X/Open XA-resourceproviders en -databases buiten Azure SQL Managed Instance kunnen bevatten, moet u DTC configureren voor Azure SQL Managed Instance.
  • Transacties tussen WCF-services worden niet ondersteund. U hebt bijvoorbeeld een WCF-servicemethode waarmee een transactie wordt uitgevoerd. Het insluiten van de aanroep binnen een transactiebereik mislukt als een System.ServiceModel.ProtocolException.
  • Azure SQL Managed Instance moet deel uitmaken van een serververtrouwensgroep om deel te nemen aan gedistribueerde transacties.
  • Beperkingen van serververtrouwensgroepen zijn van invloed op gedistribueerde transacties.
  • Beheerde exemplaren die deelnemen aan gedistribueerde transacties moeten verbinding hebben via privé-eindpunten (met behulp van privé-IP-adres uit het virtuele netwerk waar ze worden geïmplementeerd) en moeten wederzijds worden verwezen met behulp van privé-FQDN's. Clienttoepassingen kunnen gedistribueerde transacties op privé-eindpunten gebruiken. In gevallen waarin Transact-SQL gebruikmaakt van gekoppelde servers die verwijzen naar privé-eindpunten, kunnen clienttoepassingen ook gedistribueerde transacties op openbare eindpunten gebruiken. Deze beperking wordt uitgelegd in het volgende diagram.

Private endpoint connectivity limitation

Volgende stappen