Distribuované transakce v cloudových databázích

Platí pro:Azure SQL DatabaseAzure SQL Managed Instance

Tento článek popisuje použití transakcí elastické databáze, které umožňují spouštět distribuované transakce napříč cloudovými databázemi pro Azure SQL Database a Azure SQL Managed Instance. V tomto článku se termíny "distribuované transakce" a "transakce elastické databáze" považují za synonyma a používají se zaměnitelně.

Poznámka:

Ke spouštění distribuovaných transakcí ve smíšených prostředích můžete také použít koordinátor distribuovaných transakcí pro službu Azure SQL Managed Instance .

Přehled

Transakce elastické databáze pro Azure SQL Database a Azure SQL Managed Instance umožňují spouštět transakce, které zahrnují několik databází. Transakce elastické databáze jsou k dispozici pro aplikace .NET pomocí ADO.NET a integrují se se známým programovacím prostředím pomocí třídy System.Transaction . Pokud chcete získat knihovnu, přečtěte si téma .NET Framework 4.6.1 (Webový instalační program). Kromě toho jsou distribuované transakce pro spravované instance k dispozici v jazyce Transact-SQL.

Tento scénář obvykle vyžaduje spuštění programu Microsoft Distributed Transaction Coordinator (MSDTC). Vzhledem k tomu, že MSDTC není k dispozici pro Azure SQL Database, schopnost koordinovat distribuované transakce byla přímo integrována do SQL Database a SQL Managed Instance. Pro službu SQL Managed Instance však můžete také použít koordinátor distribuovaných transakcí ke spouštění distribuovaných transakcí napříč řadou smíšených prostředí, jako jsou spravované instance, SQL Servery, další systémy pro správu relačních databází (RDBMS), vlastní aplikace a další účastníci transakcí hostovaní v libovolném prostředí, které můžou navázat síťové připojení k Azure.

Aplikace se můžou připojit k jakékoli databázi a spustit distribuované transakce a jedna z databází nebo serverů transparentně koordinuje distribuovanou transakci, jak je znázorněno na následujícím obrázku.

Distributed transactions with Azure SQL Database using elastic database transactions

Obvyklé scénáře

Transakce elastické databáze umožňují aplikacím provádět atomické změny dat uložených v několika různých databázích. SQL Database i SQL Managed Instance podporují vývojové prostředí na straně klienta v jazyce C# a .NET. Prostředí na straně serveru (kód napsaný v uložených procedurách nebo skriptech na straně serveru) pomocí jazyka Transact-SQL je k dispozici pouze pro službu SQL Managed Instance.

Důležité

Spouštění transakcí elastické databáze mezi Azure SQL Database a azure SQL Managed Instance se nepodporuje. Transakce elastické databáze může zahrnovat pouze sadu databází ve službě SQL Database nebo sadu databází napříč spravovanými instancemi.

Transakce elastické databáze cílí na následující scénáře:

  • Vícebázové aplikace v Azure: V tomto scénáři se data vertikálně rozdělují mezi několik databází ve službě SQL Database nebo ve spravované instanci SQL, aby se různé druhy dat nacházet v různých databázích. Některé operace vyžadují změny dat, které se uchovávají ve dvou nebo více databázích. Aplikace používá transakce elastické databáze ke koordinaci změn napříč databázemi a zajištění atomicity.
  • Horizontálně dělené databázové aplikace v Azure: V tomto scénáři datová vrstva používá klientskou knihovnu elastické databáze nebo samoobslužné horizontální dělení dat napříč mnoha databázemi ve službě SQL Database nebo sql Managed Instance. Jedním z hlavních případů použití je potřeba provést atomické změny pro horizontálně dělenou aplikaci s více tenanty, když se změny zasahují do tenantů. Představte si například přenos z jednoho tenanta do druhého, který se bude nacházet v různých databázích. Druhým případem je jemně odstupňované horizontální dělení tak, aby vyhovovalo potřebám velkého tenanta, což zase znamená, že některé atomické operace se musí roztáhnout napříč několika databázemi používanými pro stejného tenanta. Třetím případem jsou atomické aktualizace referenčních dat, které se replikují napříč databázemi. Atomické, transactované operace v těchto řádcích se teď dají koordinovat napříč několika databázemi. Transakce elastické databáze používají dvoufázové potvrzení k zajištění atomicity transakcí napříč databázemi. Je vhodný pro transakce, které zahrnují méně než 100 databází najednou v rámci jedné transakce. Tato omezení se nevynucují, ale u transakcí elastické databáze byste měli očekávat míru výkonu a úspěšnosti při překročení těchto limitů.

Instalace a migrace

Funkce pro transakce elastické databáze jsou poskytovány prostřednictvím aktualizací knihoven .NET System.Data.dll a System.Transactions.dll. Knihovny DLL zajišťují použití dvoufázového potvrzení, pokud je to nezbytné k zajištění atomicity. Pokud chcete začít vyvíjet aplikace pomocí transakcí elastické databáze, nainstalujte rozhraní .NET Framework 4.6.1 nebo novější verzi. Při spuštění na starší verzi rozhraní .NET Framework se transakce nepodaří zvýšit na distribuovanou transakci a vyvolá se výjimka.

Po instalaci můžete použít rozhraní API distribuovaných transakcí v System.Transactions s připojeními ke službě SQL Database a spravované instanci SQL. Pokud máte existující aplikace MSDTC pomocí těchto rozhraní API, znovu sestavte stávající aplikace pro .NET 4.6 po instalaci rozhraní 4.6.1 Framework. Pokud vaše projekty cílí na .NET 4.6, automaticky použijí aktualizované knihovny DLL z nové verze rozhraní Framework a volání rozhraní API distribuovaných transakcí v kombinaci s připojeními ke službě SQL Database nebo sql Managed Instance bude nyní úspěšná.

Mějte na paměti, že transakce elastické databáze nevyžadují instalaci MSDTC. Místo toho jsou transakce elastické databáze přímo spravované službou a v rámci této služby. To výrazně zjednodušuje cloudové scénáře, protože nasazení MSDTC není nezbytné k použití distribuovaných transakcí se službou SQL Database nebo službou SQL Managed Instance. Oddíl 4 podrobněji vysvětluje, jak nasadit transakce elastické databáze a požadované rozhraní .NET Framework společně s cloudovými aplikacemi do Azure.

Instalace .NET pro Azure Cloud Services

Azure nabízí několik nabídek pro hostování aplikací .NET. Porovnání různých nabídek je k dispozici ve srovnání se službami Aplikace Azure, cloudovými službami a virtuálními počítači. Pokud je hostovaný operační systém nabídky menší než .NET 4.6.1 vyžadovaný pro elastické transakce, musíte upgradovat hostovaný operační systém na verzi 4.6.1.

Pro službu Aplikace Azure se v současné době nepodporují upgrady na hostovaný operační systém. V případě virtuálních počítačů Azure se jednoduše přihlaste k virtuálnímu počítači a spusťte instalační program pro nejnovější rozhraní .NET Framework. Pro Azure Cloud Services musíte do spouštěcích úloh nasazení zahrnout instalaci novější verze .NET. Koncepty a kroky jsou popsané v tématu Instalace .NET v roli cloudové služby.

Upozorňujeme, že instalační program pro .NET 4.6.1 může během procesu spouštění v cloudových službách Azure vyžadovat větší dočasné úložiště než instalační program pro .NET 4.6. Pokud chcete zajistit úspěšnou instalaci, musíte zvýšit dočasné úložiště cloudové služby Azure v souboru ServiceDefinition.csdef v části LocalResources a nastavení prostředí spouštěcí úlohy, jak je znázorněno v následující ukázce:

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

Vývojové prostředí .NET

Vícefaktorové aplikace

Následující ukázkový kód používá známé programovací prostředí pro .NET System.Transactions. TransactionScope třída vytváří okolí transakce v .NET. ("okolí transakce" je ten, který žije v aktuálním vlákně.) Všechna připojení otevřená v rámci TransactionScope se účastní transakce. Pokud se různé databáze účastní, transakce je automaticky zvýšena na distribuovanou transakci. Výsledek transakce je řízen nastavením rozsahu na dokončení indikovat potvrzení.

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

Horizontálně dělené databázové aplikace

Transakce elastické databáze pro SLUŽBU SQL Database a sql Managed Instance také podporují koordinaci distribuovaných transakcí, ve kterých používáte metodu Open Připojení ionForKey klientské knihovny elastické databáze k otevření připojení pro datovou vrstvu se škálováním na více instancí. Zvažte případy, kdy potřebujete zaručit transakční konzistenci pro změny v několika různých hodnotách klíče horizontálního dělení. Připojení pro horizontální oddíly hostující různé hodnoty klíče horizontálního dělení se zprostředkovávají pomocí Open Připojení ionForKey. V obecném případě mohou být připojení k různým horizontálním oddílům, aby se zajistilo, že transakční záruky vyžadují distribuovanou transakci. Tento přístup ilustruje následující ukázka kódu. Předpokládá se, že proměnná shardmap se používá k reprezentaci mapy horizontálních oddílů z klientské knihovny elastické databáze:

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

Vývojové prostředí transact-SQL

Distribuované transakce na straně serveru využívající Transact-SQL jsou k dispozici pouze pro službu Azure SQL Managed Instance. Distribuovanou transakci lze spustit pouze mezi instancemi, které patří do stejné skupiny důvěryhodnosti serveru. V tomto scénáři musí spravované instance používat odkazovaný server k vzájemnému propojení.

Následující ukázkový kód Transact-SQL používá BEGIN DISTRIBUTED TRANSACTION ke spuštění distribuované transakce.

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

Kombinování vývojového prostředí .NET a Transact-SQL

Aplikace .NET, které používají Třídy System.Transaction mohou kombinovat TransactionScope třídy s příkazem Transact-SQL BEGIN DISTRIBUTED TRANSACTION. Uvnitř TransactionScope vnitřní transakce, která spouští BEGIN DISTRIBUTED TRANSACTION bude explicitně povýšena na distribuovanou transakci. Také, když druhý Sql Připojení on je otevřen v TransactionScope bude implicitně povýšen na distribuovanou transakci. Po spuštění distribuované transakce se všechny následné transakce požadavky, ať už pocházejí z .NET nebo Transact-SQL, připojí nadřazenou distribuovanou transakci. V důsledku toho všechny vnořené obory transakcí iniciované příkazem BEGIN skončí ve stejných transakcích a příkazy COMMIT/ROLLBACK budou mít následující vliv na celkový výsledek:

  • Příkaz COMMIT nebude mít žádný vliv na obor transakce iniciovaný příkazem BEGIN, to znamená, že žádné výsledky nebudou potvrzeny před Complete() metoda je vyvolána TransactionScope objektu. Pokud je objekt TransactionScope zničen před dokončením, všechny změny provedené v rámci oboru se vrátí zpět.
  • Příkaz ROLLBACK způsobí vrácení celého TransactionScope zpět. Všechny pokusy o zařazení nových transakcí v TransactionScope později selžou, stejně jako pokus vyvolat Complete() na TransactionScope objektu.

Zde je příklad, kde transakce je explicitně povýšena na distribuovanou transakci s 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();
}

Následující příklad ukazuje transakci, která je implicitně povýšena na distribuovanou transakci po druhém Sql Připojení on byl spuštěn v 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();
}

Transakce pro SLUŽBU SQL Database

Transakce elastické databáze se podporují napříč různými servery ve službě Azure SQL Database. Při transakcích mezi hranicemi serveru je třeba nejprve zadat zúčastněné servery do vzájemného komunikačního vztahu. Po navázání komunikačního vztahu se každá databáze na jakémkoli ze dvou serverů může účastnit elastických transakcí s databázemi z druhého serveru. U transakcí, které pokrývají více než dva servery, musí být pro všechny páry serverů zaveden komunikační vztah.

Ke správě vztahů komunikace mezi servery pro transakce elastické databáze použijte následující rutiny PowerShellu:

  • New-AzSqlServerCommunicationLink: Pomocí této rutiny vytvořte nový komunikační vztah mezi dvěma servery ve službě Azure SQL Database. Vztah je symetrický, což znamená, že oba servery mohou iniciovat transakce s druhým serverem.
  • Get-AzSqlServerCommunicationLink: Pomocí této rutiny můžete načíst existující vztahy komunikace a jejich vlastnosti.
  • Remove-AzSqlServerCommunicationLink: Pomocí této rutiny odeberte existující komunikační vztah.

Transakce pro spravovanou instanci SQL

Distribuované transakce jsou podporovány napříč databázemi v rámci více instancí. Když transakce překračují hranice spravované instance, musí být zúčastněné instance ve vzájemném vztahu zabezpečení a komunikace. To se provádí vytvořením skupiny důvěryhodnosti serveru, kterou můžete provést pomocí webu Azure Portal, Azure PowerShellu nebo Azure CLI. Pokud instance nejsou ve stejné virtuální síti, musíte nakonfigurovat partnerský vztah virtuálních sítí a příchozí a odchozí pravidla skupiny zabezpečení sítě, která musí umožňovat porty 5024 a 11000–12000 ve všech zúčastněných virtuálních sítích.

Server Trust Groups on Azure Portal

Následující diagram znázorňuje skupinu důvěryhodnosti serveru se spravovanými instancemi, které můžou spouštět distribuované transakce pomocí .NET nebo Transact-SQL:

Distributed transactions with Azure SQL Managed Instance using elastic transactions

Monitorování stavu transakcí

Pomocí zobrazení dynamické správy (DMV) můžete monitorovat stav a průběh probíhajících transakcí elastické databáze. Všechna zobrazení dynamické správy související s transakcemi jsou relevantní pro distribuované transakce ve službě SQL Database a ve spravované instanci SQL. Odpovídající seznam zobrazení dynamické správy najdete tady: Zobrazení a funkce související s transakcemi dynamické správy (Transact-SQL).

Tato zobrazení dynamické správy jsou obzvláště užitečná:

  • sys.dm_tran_active_transactions: Zobrazuje seznam aktuálně aktivních transakcí a jejich stav. Sloupec UOW (Unit Of Work) může identifikovat různé podřízené transakce, které patří do stejné distribuované transakce. Všechny transakce ve stejné distribuované transakci mají stejnou hodnotu UOW. Další informace najdete v dokumentaci k zobrazení dynamické správy.
  • sys.dm_tran_database_transactions: Poskytuje další informace o transakcích, jako je umístění transakce v protokolu. Další informace najdete v dokumentaci k zobrazení dynamické správy.
  • sys.dm_tran_locks: Poskytuje informace o zámkech, které jsou aktuálně uloženy probíhajícími transakcemi. Další informace najdete v dokumentaci k zobrazení dynamické správy.

Omezení

Pro transakce elastické databáze ve službě SQL Database se aktuálně vztahují následující omezení:

  • Podporují se pouze transakce napříč databázemi ve službě SQL Database. Ostatní poskytovatelé prostředků X/Open XA a databáze mimo SLUŽBU SQL Database se nemůžou účastnit transakcí elastické databáze. To znamená, že transakce elastické databáze se nemůžou roztáhnout mezi místním SQL Serverem a službou Azure SQL Database. U distribuovaných transakcí v místním prostředí nadále používejte MSDTC.
  • Podporují se pouze transakce koordinované klientem z aplikace .NET. Podpora T-SQL na straně serveru, jako je NAPŘÍKLAD BEGIN DISTRIBUTED TRANSACTION, se plánuje, ale zatím není k dispozici.
  • Transakce napříč službami WCF se nepodporují. Máte například metodu služby WCF, která provádí transakci. Uzavření volání do oboru transakce selže jako System.ServiceModel.ProtocolException.

Pro distribuované transakce (označované také jako elastické transakce nebo nativně podporované distribuované transakce) ve službě SQL Managed Instance platí následující omezení:

  • Díky této technologii se podporují pouze transakce napříč databázemi ve spravovaných instancích. Pro všechny ostatní scénáře, které mohou zahrnovat poskytovatele prostředků X/Open XA a databáze mimo Azure SQL Managed Instance, byste měli nakonfigurovat DTC pro Azure SQL Managed Instance.
  • Transakce napříč službami WCF se nepodporují. Máte například metodu služby WCF, která provádí transakci. Uzavření volání do oboru transakce selže jako System.ServiceModel.ProtocolException.
  • Spravovaná instance Azure SQL musí být součástí skupiny důvěryhodnosti serveru, aby se mohla účastnit distribuované transakce.
  • Omezení skupin důvěryhodnosti serveru ovlivňují distribuované transakce.
  • Spravované instance, které se účastní distribuovaných transakcí, musí mít připojení přes privátní koncové body (pomocí privátní IP adresy z virtuální sítě, kde jsou nasazené) a musí se vzájemně odkazovat pomocí privátních plně kvalifikovaných názvů domén. Klientské aplikace můžou používat distribuované transakce v privátních koncových bodech. Kromě toho v případech, kdy Transact-SQL využívá propojené servery odkazující na privátní koncové body, můžou klientské aplikace používat také distribuované transakce na veřejných koncových bodech. Toto omezení je vysvětleno v následujícím diagramu.

Private endpoint connectivity limitation

Další kroky