Transakcje rozproszone w bazach danych w chmurze

Dotyczy: Azure SQL DatabaseAzure SQL Managed Instance

W tym artykule opisano używanie elastycznych transakcji bazy danych, które umożliwiają uruchamianie transakcji rozproszonych w bazach danych w chmurze dla usług Azure SQL Database i Azure SQL Managed Instance. W tym artykule terminy "transakcje rozproszone" i "elastyczne transakcje bazy danych" są uznawane za synonimy i są używane zamiennie.

Uwaga

Można również użyć koordynatora transakcji rozproszonych dla usługi Azure SQL Managed Instance do uruchamiania transakcji rozproszonych w środowiskach mieszanych.

Omówienie

Elastyczne transakcje baz danych dla usług Azure SQL Database i Azure SQL Managed Instance umożliwiają uruchamianie transakcji obejmujących kilka baz danych. Elastyczne transakcje baz danych są dostępne dla aplikacji platformy .NET przy użyciu ADO.NET i integrują się ze znanym środowiskiem programowania przy użyciu klas System.Transaction . Aby uzyskać bibliotekę, zobacz .NET Framework 4.6.1 (Instalator sieci Web). Ponadto w przypadku transakcji rozproszonych wystąpienia zarządzanego są dostępne w języku Transact-SQL.

W środowisku lokalnym taki scenariusz zwykle wymaga uruchomienia koordynatora transakcji rozproszonych firmy Microsoft (MSDTC). Ponieważ usługa MSDTC nie jest dostępna dla usługi Azure SQL Database, możliwość koordynowania transakcji rozproszonych została bezpośrednio zintegrowana z usługami SQL Database i SQL Managed Instance. Jednak w przypadku usługi SQL Managed Instance można również użyć koordynatora transakcji rozproszonych do uruchamiania transakcji rozproszonych w wielu środowiskach mieszanych, takich jak między wystąpieniami zarządzanymi, serwerami SQL, innymi systemami zarządzania relacyjnymi bazami danych (RDBMS), aplikacjami niestandardowymi i innymi uczestnikami transakcji hostowanymi w dowolnym środowisku, które mogą ustanowić łączność sieciową z platformą Azure.

Aplikacje mogą łączyć się z dowolną bazą danych w celu uruchomienia transakcji rozproszonych, a jedna z baz danych lub serwerów będzie w sposób niewidoczny koordynować transakcję rozproszoną, jak pokazano na poniższym rysunku.

Distributed transactions with Azure SQL Database using elastic database transactions

Typowe scenariusze

Elastyczne transakcje bazy danych umożliwiają aplikacjom wprowadzanie niepodzielnych zmian w danych przechowywanych w kilku różnych bazach danych. Zarówno usługa SQL Database, jak i wystąpienie zarządzane SQL obsługują środowiska programistyczne po stronie klienta w językach C# i .NET. Środowisko po stronie serwera (kod napisany w procedurach składowanych lub skryptach po stronie serwera) przy użyciu języka Transact-SQL jest dostępne tylko dla usługi SQL Managed Instance.

Ważne

Uruchamianie transakcji elastycznej bazy danych między usługą Azure SQL Database i usługą Azure SQL Managed Instance nie jest obsługiwane. Transakcja elastycznej bazy danych może obejmować tylko zestaw baz danych w usłudze SQL Database lub zestaw baz danych w wystąpieniach zarządzanych.

Transakcje elastycznej bazy danych są przeznaczone dla następujących scenariuszy:

  • Aplikacje z wieloma bazami danych na platformie Azure: w tym scenariuszu dane są partycjonowane pionowo w kilku bazach danych w usłudze SQL Database lub w wystąpieniu zarządzanym SQL, tak aby różne rodzaje danych znajdowały się w różnych bazach danych. Niektóre operacje wymagają zmian danych, które są przechowywane w co najmniej dwóch bazach danych. Aplikacja używa elastycznych transakcji bazy danych do koordynowania zmian w bazach danych i zapewnienia niepodzielności.
  • Aplikacje bazy danych podzielone na fragmenty na platformie Azure: w tym scenariuszu warstwa danych używa biblioteki klienta elastic Database lub samodzielnego fragmentowania w celu partycjonowania danych w poziomie w wielu bazach danych w usłudze SQL Database lub w wystąpieniu zarządzanym SQL. Jednym z widocznych przypadków użycia jest konieczność wykonania niepodzielnych zmian dla aplikacji wielodostępnej podzielonej na fragmenty, gdy zmiany obejmują dzierżawy. Pomyśl na przykład o przeniesieniu z jednej dzierżawy do innej, zarówno znajdujących się w różnych bazach danych. Drugi przypadek to szczegółowe fragmentowanie w celu zaspokojenia potrzeb związanych z pojemnością dużej dzierżawy, co z kolei zwykle oznacza, że niektóre operacje niepodzielne muszą rozciągać się na kilka baz danych używanych dla tej samej dzierżawy. Trzeci przypadek to niepodzielne aktualizacje danych referencyjnych replikowanych w bazach danych. Niepodzielne, transakcyjne operacje wzdłuż tych linii można teraz koordynować w kilku bazach danych. Transakcje elastycznej bazy danych używają zatwierdzenia dwufazowego w celu zapewnienia niepodzielności transakcji w bazach danych. Jest to dobre rozwiązanie dla transakcji, które obejmują mniej niż 100 baz danych w czasie w ramach jednej transakcji. Te limity nie są wymuszane, ale należy oczekiwać, że wydajność i współczynniki powodzenia dla elastycznych transakcji bazy danych będą cierpieć w przypadku przekroczenia tych limitów.

Instalacja i migracja

Funkcje transakcji elastycznej bazy danych są udostępniane za pośrednictwem aktualizacji bibliotek platformy .NET System.Data.dll i System.Transactions.dll. Biblioteki DLL zapewniają, że zatwierdzenie dwufazowe jest używane w razie potrzeby w celu zapewnienia niepodzielności. Aby rozpocząć tworzenie aplikacji przy użyciu transakcji elastycznej bazy danych, zainstaluj program .NET Framework 4.6.1 lub nowszą wersję. W przypadku uruchamiania we wcześniejszej wersji programu .NET Framework transakcje nie będą podwyższać poziomu do transakcji rozproszonej i zostanie zgłoszony wyjątek.

Po instalacji można użyć interfejsów API transakcji rozproszonych w system.Transactions z połączeniami z usługą SQL Database i wystąpieniem zarządzanym SQL. Jeśli masz istniejące aplikacje MSDTC korzystające z tych interfejsów API, ponownie skompiluj istniejące aplikacje dla platformy .NET 4.6 po zainstalowaniu programu Framework 4.6.1. Jeśli projekty są przeznaczone dla platformy .NET 4.6, będą automatycznie używać zaktualizowanych bibliotek DLL z nowej wersji platformy i wywołań interfejsu API transakcji rozproszonych w połączeniu z połączeniami z usługą SQL Database lub wystąpieniem zarządzanym SQL zakończy się teraz pomyślnie.

Pamiętaj, że transakcje elastycznej bazy danych nie wymagają instalowania witryny MSDTC. Zamiast tego elastyczne transakcje bazy danych są zarządzane bezpośrednio przez usługę i w ramach tej usługi. Znacznie upraszcza to scenariusze chmury, ponieważ wdrożenie usługi MSDTC nie jest konieczne do używania transakcji rozproszonych z usługą SQL Database lub wystąpieniem zarządzanym SQL. Sekcja 4 zawiera bardziej szczegółowe informacje na temat wdrażania elastycznych transakcji bazy danych i wymaganej platformy .NET Framework wraz z aplikacjami w chmurze na platformie Azure.

Instalacja platformy .NET dla usług Azure Cloud Services

Platforma Azure oferuje kilka ofert hostowania aplikacji platformy .NET. Porównanie różnych ofert jest dostępne w porównaniu aplikacja systemu Azure Service, Cloud Services i Virtual Machines. Jeśli system operacyjny gościa oferty jest mniejszy niż .NET 4.6.1 wymagany dla transakcji elastycznych, należy uaktualnić system operacyjny gościa do wersji 4.6.1.

W przypadku usługi aplikacja systemu Azure uaktualnienia do systemu operacyjnego gościa nie są obecnie obsługiwane. W przypadku usługi Azure Virtual Machines wystarczy zalogować się do maszyny wirtualnej i uruchomić instalatora najnowszej platformy .NET Framework. W przypadku usług Azure Cloud Services należy dołączyć instalację nowszej wersji platformy .NET do zadań uruchamiania wdrożenia. Pojęcia i kroki opisano w temacie Instalowanie platformy .NET w roli usługi w chmurze.

Należy pamiętać, że instalator programu .NET 4.6.1 może wymagać większej ilości magazynu tymczasowego podczas procesu uruchamiania w usługach w chmurze platformy Azure niż instalator programu .NET 4.6. Aby zapewnić pomyślną instalację, należy zwiększyć magazyn tymczasowy dla usługi w chmurze platformy Azure w pliku ServiceDefinition.csdef w sekcji LocalResources i ustawienia środowiska zadania uruchamiania, jak pokazano w poniższym przykładzie:

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

Środowisko programistyczne platformy .NET

Aplikacje z wieloma bazami danych

Poniższy przykładowy kod używa znanego środowiska programowania z platformą .NET System.Transactions. Klasa TransactionScope ustanawia transakcję otoczenia na platformie .NET. (Transakcja otoczenia jest taka, która znajduje się w bieżącym wątku). Wszystkie połączenia otwarte w transakcji TransactionScope uczestniczą w transakcji. Jeśli różne bazy danych uczestniczą, transakcja jest automatycznie podwyższona do transakcji rozproszonej. Wynik transakcji jest kontrolowany przez ustawienie zakresu, aby zakończyć, aby wskazać zatwierdzenie.

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

Aplikacje bazy danych podzielone na fragmenty

Elastyczne transakcje baz danych dla usług SQL Database i SQL Managed Instance obsługują również koordynowanie transakcji rozproszonych, w których używasz metody Open Połączenie ionForKey elastycznej biblioteki klienta bazy danych do otwierania połączeń dla skalowanej w poziomie warstwy danych. Rozważ przypadki, w których należy zagwarantować spójność transakcyjną zmian w kilku różnych wartościach klucza fragmentowania. Połączenie do fragmentów hostujących różne wartości kluczy fragmentowania są obsługiwane przy użyciu polecenia Open Połączenie ionForKey. W ogólnym przypadku połączenia mogą być z różnymi fragmentami, dzięki czemu zapewnienie gwarancji transakcyjnych wymaga transakcji rozproszonej. Poniższy przykładowy kod ilustruje to podejście. Przyjęto założenie, że zmienna o nazwie shardmap jest używana do reprezentowania mapy fragmentów z elastycznej biblioteki klienta bazy danych:

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

Środowisko programistyczne języka Transact-SQL

Transakcje rozproszone po stronie serwera przy użyciu języka Transact-SQL są dostępne tylko dla usługi Azure SQL Managed Instance. Transakcja rozproszona może być wykonywana tylko między wystąpieniami należącymi do tej samej grupy zaufania serwera. W tym scenariuszu wystąpienia zarządzane muszą odwoływać się do siebie przy użyciu serwera połączonego.

Poniższy przykładowy kod Języka Transact-SQL używa funkcji BEGIN DISTRIBUTED TRANSACTION do rozpoczęcia transakcji rozproszonej.

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

Łączenie środowiska programistycznego platformy .NET i języka Transact-SQL

Aplikacje platformy .NET korzystające z klas System.Transaction mogą łączyć klasę TransactionScope z instrukcją Transact-SQL BEGIN DISTRIBUTED TRANSACTION. W ramach TransactionScope, transakcja wewnętrzna, która wykonuje BEGIN DISTRIBUTED TRANSACTION zostanie jawnie podwyższony do transakcji rozproszonej. Ponadto po otwarciu drugiego sql Połączenie on w transactionscope będzie niejawnie promowany do transakcji rozproszonej. Po rozpoczęciu transakcji rozproszonej wszystkie kolejne żądania transakcji, niezależnie od tego, czy pochodzą z platformy .NET, czy transact-SQL, dołączą nadrzędną transakcję rozproszoną. W związku z tym wszystkie zagnieżdżone zakresy transakcji inicjowane przez instrukcję BEGIN zostaną uwzględnione w tej samej transakcji, a instrukcje COMMIT/ROLLBACK będą miały następujący wpływ na ogólny wynik:

  • Instrukcja COMMIT nie będzie miała żadnego wpływu na zakres transakcji zainicjowany przez instrukcję BEGIN, czyli nie zostaną zatwierdzone żadne wyniki przed wywołania metody Complete() w obiekcie TransactionScope. Jeśli obiekt TransactionScope zostanie zniszczony przed zakończeniem, wszystkie zmiany wprowadzone w zakresie zostaną wycofane.
  • Instrukcja ROLLBACK spowoduje wycofanie całego elementu TransactionScope. Wszelkie próby rejestracji nowych transakcji w TransactionScope zakończą się niepowodzeniem później, a także próba wywołania Complete() w obiekcie TransactionScope.

Oto przykład, w którym transakcja jest jawnie promowana do transakcji rozproszonej za pomocą języka 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();
}

W poniższym przykładzie pokazano transakcję, która jest niejawnie awansowana do transakcji rozproszonej, gdy drugi sql Połączenie on został uruchomiony w 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();
}

Transakcje dla usługi SQL Database

Transakcje elastycznej bazy danych są obsługiwane na różnych serwerach w usłudze Azure SQL Database. Gdy transakcje przekraczają granice serwera, należy najpierw wprowadzić uczestniczących serwerów w relację wzajemnej komunikacji. Po ustanowieniu relacji komunikacji każda baza danych na każdym z dwóch serwerów może uczestniczyć w elastycznych transakcjach z bazami danych z drugiego serwera. W przypadku transakcji obejmujących więcej niż dwa serwery relacja komunikacji musi być w miejscu dla dowolnej pary serwerów.

Użyj następujących poleceń cmdlet programu PowerShell, aby zarządzać relacjami komunikacji między serwerami dla elastycznych transakcji bazy danych:

  • New-AzSqlServerCommunicationLink: użyj tego polecenia cmdlet, aby utworzyć nową relację komunikacji między dwoma serwerami w usłudze Azure SQL Database. Relacja jest symetryczna, co oznacza, że oba serwery mogą inicjować transakcje z innym serwerem.
  • Get-AzSqlServerCommunicationLink: użyj tego polecenia cmdlet, aby pobrać istniejące relacje komunikacji i ich właściwości.
  • Remove-AzSqlServerCommunicationLink: użyj tego polecenia cmdlet, aby usunąć istniejącą relację komunikacji.

Transakcje dla usługi SQL Managed Instance

Transakcje rozproszone są obsługiwane w bazach danych w wielu wystąpieniach. Gdy transakcje przekraczają granice wystąpienia zarządzanego, wystąpienia uczestniczące muszą być we wzajemnej relacji zabezpieczeń i komunikacji. W tym celu należy utworzyć grupę zaufania serwera, którą można wykonać za pomocą witryny Azure Portal lub programu Azure PowerShell lub interfejsu wiersza polecenia platformy Azure. Jeśli wystąpienia nie znajdują się w tej samej sieci wirtualnej, należy skonfigurować komunikację równorzędną sieci wirtualnych i reguły ruchu przychodzącego i wychodzącego sieciowej grupy zabezpieczeń muszą zezwalać na porty 5024 i 11000-12000 we wszystkich uczestniczących sieciach wirtualnych.

Server Trust Groups on Azure Portal

Na poniższym diagramie przedstawiono grupę zaufania serwera z wystąpieniami zarządzanymi, które mogą wykonywać transakcje rozproszone za pomocą platformy .NET lub języka Transact-SQL:

Distributed transactions with Azure SQL Managed Instance using elastic transactions

Monitorowanie stanu transakcji

Użyj dynamicznych widoków zarządzania (DMV), aby monitorować stan i postęp bieżących elastycznych transakcji bazy danych. Wszystkie dynamiczne widoki zarządzania związane z transakcjami są istotne dla transakcji rozproszonych w usługach SQL Database i SQL Managed Instance. Odpowiednią listę dynamicznych widoków zarządzania można znaleźć tutaj: Dynamiczne widoki zarządzania transakcjami i funkcje (Transact-SQL).

Te dynamiczne widoki zarządzania są szczególnie przydatne:

  • sys.dm_tran_active_transactions: Wyświetla listę aktualnie aktywnych transakcji i ich stan. Kolumna UOW (Unit Of Work) może zidentyfikować różne transakcje podrzędne, które należą do tej samej transakcji rozproszonej. Wszystkie transakcje w ramach tej samej transakcji rozproszonej mają tę samą wartość UOW. Aby uzyskać więcej informacji, zobacz dokumentację dmv.
  • sys.dm_tran_database_transactions: udostępnia dodatkowe informacje o transakcjach, takie jak umieszczanie transakcji w dzienniku. Aby uzyskać więcej informacji, zobacz dokumentację dmv.
  • sys.dm_tran_locks: zawiera informacje o blokadach, które są obecnie przechowywane przez bieżące transakcje. Aby uzyskać więcej informacji, zobacz dokumentację dmv.

Ograniczenia

Następujące ograniczenia dotyczą obecnie transakcji elastycznej bazy danych w usłudze SQL Database:

  • Obsługiwane są tylko transakcje w bazach danych w usłudze SQL Database. Inni dostawcy zasobów X/Open XA i bazy danych spoza usługi SQL Database nie mogą uczestniczyć w transakcjach elastycznych baz danych. Oznacza to, że elastyczne transakcje baz danych nie mogą rozciągać się na lokalny program SQL Server i usługę Azure SQL Database. W przypadku transakcji rozproszonych w środowisku lokalnym kontynuuj korzystanie z witryny MSDTC.
  • Obsługiwane są tylko transakcje koordynowane przez klienta z aplikacji .NET. Obsługa języka T-SQL po stronie serwera, taka jak BEGIN DISTRIBUTED TRANSACTION, jest planowana, ale nie jest jeszcze dostępna.
  • Transakcje w usługach WCF nie są obsługiwane. Na przykład masz metodę usługi WCF, która wykonuje transakcję. Ujęcie wywołania w zakresie transakcji zakończy się niepowodzeniem jako Element System.ServiceModel.ProtocolException.

Następujące ograniczenia dotyczą obecnie transakcji rozproszonych (nazywanych również elastycznymi transakcjami lub natywnie obsługiwanymi transakcjami rozproszonymi) w usłudze SQL Managed Instance:

  • Dzięki tej technologii obsługiwane są tylko transakcje w bazach danych w wystąpieniach zarządzanych. W przypadku wszystkich innych scenariuszy, które mogą obejmować dostawców zasobów X/Otwórz XA i bazy danych poza usługą Azure SQL Managed Instance, należy skonfigurować usługę DTC dla usługi Azure SQL Managed Instance.
  • Transakcje w usługach WCF nie są obsługiwane. Na przykład masz metodę usługi WCF, która wykonuje transakcję. Ujęcie wywołania w zakresie transakcji zakończy się niepowodzeniem jako Element System.ServiceModel.ProtocolException.
  • Usługa Azure SQL Managed Instance musi należeć do grupy zaufania serwera, aby móc uczestniczyć w transakcji rozproszonej.
  • Ograniczenia grup zaufania serwera mają wpływ na transakcje rozproszone.
  • Wystąpienia zarządzane, które uczestniczą w transakcjach rozproszonych, muszą mieć łączność za pośrednictwem prywatnych punktów końcowych (przy użyciu prywatnego adresu IP z sieci wirtualnej, w której są wdrożone) i muszą być wzajemnie przywoływane przy użyciu prywatnych nazw FQDN. Aplikacje klienckie mogą używać transakcji rozproszonych w prywatnych punktach końcowych. Ponadto w przypadkach, gdy język Transact-SQL korzysta z serwerów połączonych odwołujące się do prywatnych punktów końcowych, aplikacje klienckie mogą również używać transakcji rozproszonych w publicznych punktach końcowych. To ograniczenie zostało wyjaśnione na poniższym diagramie.

Private endpoint connectivity limitation

Następne kroki