Sdílet prostřednictvím


Použití směrování závislého na datech ke směrování dotazu do příslušné databáze

Platí pro: Azure SQL Database

Směrování závislé na datech je schopnost pomocí dat v dotazu směrovat požadavek do příslušné databáze. Směrování závislé na datech je základním vzorem při práci s horizontálně dělenými databázemi. Kontext požadavku lze také použít ke směrování požadavku, zejména pokud klíč horizontálního dělení není součástí dotazu. Každý konkrétní dotaz nebo transakce v aplikaci využívající směrování závislé na datech je omezený na přístup k jedné databázi na každý požadavek. U elastických nástrojů Azure SQL Database se toto směrování provádí pomocí třídy ShardMapManager (Java, .NET).

Aplikace nemusí sledovat různé připojovací řetězec ani umístění databáze přidružené k různým řezům dat v horizontálně děleném prostředí. Místo toho Správce mapování horizontálních oddílů otevře připojení ke správným databázím v případě potřeby na základě dat v mapě horizontálních oddílů a hodnoty klíče horizontálního dělení, který je cílem požadavku aplikace. Klíč je obvykle customer_id, tenant_id, date_key nebo jiný konkrétní identifikátor, který je základním parametrem požadavku databáze.

Další informace najdete v tématu Horizontální navýšení kapacity SQL Serveru se směrováním závislým na datech.

Stažení klientské knihovny

Ke stažení:

  • Verze knihovny v Javě najdete v centrálním úložišti Maven.
  • Verze knihovny .NET, viz NuGet.

Použití objektu ShardMapManager v aplikaci směrování závislé na datech

Aplikace by během inicializace měly vytvořit instanci objektu ShardMapManager pomocí metody GetSQLShardMapManager (Java, .NET). V tomto příkladu se inicializuje objekt ShardMapManager i konkrétní objekt ShardMap , který obsahuje. Tento příklad ukazuje metody GetSqlShardMapManager a GetRangeShardMap (Java, .NET).

ShardMapManager smm = ShardMapManagerFactory.getSqlShardMapManager(connectionString, ShardMapManagerLoadPolicy.Lazy);
RangeShardMap<int> rangeShardMap = smm.getRangeShardMap(Configuration.getRangeShardMapName(), ShardKeyType.Int32);
ShardMapManager smm = ShardMapManagerFactory.GetSqlShardMapManager(smmConnectionString, ShardMapManagerLoadPolicy.Lazy);
RangeShardMap<int> customerShardMap = smm.GetRangeShardMap<int>("customerMap"); 

Získání mapy horizontálních oddílů s využitím přihlašovacích údajů s nejnižšími oprávněními

Pokud aplikace nebude manipulovat s mapováním horizontálních oddílů, přihlašovací údaje použité v metodě továrny by měly mít oprávnění jen pro čtení v databázi globální mapy horizontálních oddílů. Tyto přihlašovací údaje se obvykle liší od přihlašovacích údajů používaných k otevření připojení ke správci mapování horizontálních oddílů. Viz také Přihlašovací údaje používané pro přístup k klientské knihovně elastické databáze.

Volání metody OpenConnectionForKey

Metoda ShardMap.OpenConnectionForKey (Java, .NET) vrací připojení připravené k vydávání příkazů k příslušné databázi na základě hodnoty parametru klíče. Informace o horizontálním oddílu jsou uloženy v mezipaměti v aplikaci nástrojem ShardMapManager, takže tyto požadavky obvykle nezahrnují vyhledávání databáze v databázi globální mapy horizontálních oddílů.

// Syntax:
public Connection openConnectionForKey(Object key, String connectionString, ConnectionOptions options)
// Syntax:
public SqlConnection OpenConnectionForKey<TKey>(TKey key, string connectionString, ConnectionOptions options)
  • Parametr klíče se používá jako vyhledávací klíč do mapy horizontálních oddílů k určení vhodné databáze pro požadavek.
  • Připojovací řetězec slouží pouze k předání přihlašovacích údajů uživatele pro požadované připojení. V tomto připojovacím řetězce není zahrnut žádný název databáze ani název serveru, protože metoda určuje databázi a server pomocí objektu ShardMap.
  • Vlastnost connectionOptions (Java, .NET) by měla být nastavená na ConnectionOptions.Validate , pokud se v důsledku operací rozdělení nebo sloučení může změnit mapování horizontálních oddílů a řádky se můžou přesunout do jiných databází. Toto ověření zahrnuje krátký dotaz na mapování místních horizontálních oddílů v cílové databázi (ne na globální mapování horizontálních oddílů) před doručením připojení do aplikace.

Pokud ověření proti mapování místních horizontálních oddílů selže (což znamená, že mezipaměť není správná), Správce mapování horizontálních oddílů se dotazuje na globální mapování horizontálních oddílů, aby získal novou správnou hodnotu pro vyhledávání, aktualizaci mezipaměti a získání a vrácení příslušného databázového připojení.

ConnectionOptions.None použijte pouze v případech, kdy se změny mapování horizontálních oddílů neočekávají, když je aplikace online. V takovém případě se hodnoty uložené v mezipaměti dají předpokládat, že jsou vždy správné a navíc je možné bezpečně přeskočit volání ověření odezvy cílové databáze. Tím se snižuje provoz databáze. Parametr connectionOptions může být také nastaven prostřednictvím hodnoty v konfiguračním souboru, aby bylo možné určit, jestli se během časového období očekává změny horizontálního dělení nebo ne.

Tento příklad používá hodnotu celočíselného klíče CustomerID pomocí objektu ShardMap s názvem customerShardMap.

int customerId = 12345;
int productId = 4321;
// Looks up the key in the shard map and opens a connection to the shard
try (Connection conn = shardMap.openConnectionForKey(customerId, Configuration.getCredentialsConnectionString())) {
    // Create a simple command that will insert or update the customer information
    PreparedStatement ps = conn.prepareStatement("UPDATE Sales.Customer SET PersonID = ? WHERE CustomerID = ?");

    ps.setInt(1, productId);
    ps.setInt(2, customerId);
    ps.executeUpdate();
} catch (SQLException e) {
    e.printStackTrace();
}
int customerId = 12345;
int newPersonId = 4321;

// Connect to the shard for that customer ID. No need to call a SqlConnection
// constructor followed by the Open method.
using (SqlConnection conn = customerShardMap.OpenConnectionForKey(customerId, Configuration.GetCredentialsConnectionString(), ConnectionOptions.Validate))
{
    // Execute a simple command.
    SqlCommand cmd = conn.CreateCommand();
    cmd.CommandText = @"UPDATE Sales.Customer
                        SET PersonID = @newPersonID WHERE CustomerID = @customerID";

    cmd.Parameters.AddWithValue("@customerID", customerId);cmd.Parameters.AddWithValue("@newPersonID", newPersonId);
    cmd.ExecuteNonQuery();
}  

Metoda OpenConnectionForKey vrátí nové již otevřené připojení ke správné databázi. Připojení využívaná tímto způsobem stále plně využívají sdružování připojení.

Metoda OpenConnectionForKeyAsync (Java, .NET) je k dispozici také v případě, že vaše aplikace používá asynchronní programování.

Integrace s přechodným zpracováním chyb

Osvědčeným postupem při vývoji aplikací pro přístup k datům v cloudu je zajistit, aby aplikace zachytila přechodné chyby a aby se operace několikrát opakovat před vyvoláním chyby. Zpracování přechodných chyb pro cloudové aplikace je popsáno v tématu Zpracování přechodných chyb (Java, .NET).

Zpracování přechodných chyb může přirozeně existovat se vzorem směrování závislého na datech. Klíčovým požadavkem je opakovat celý požadavek na přístup k datům, včetně bloku using , který získal připojení směrování závislého na datech. Předchozí příklad lze přepsat následujícím způsobem.

Příklad – směrování závislé na datech s přechodným zpracováním chyb

int customerId = 12345;
int productId = 4321;
try {
    SqlDatabaseUtils.getSqlRetryPolicy().executeAction(() -> {
        // Looks up the key in the shard map and opens a connection to the shard
        try (Connection conn = shardMap.openConnectionForKey(customerId, Configuration.getCredentialsConnectionString())) {
            // Create a simple command that will insert or update the customer information
            PreparedStatement ps = conn.prepareStatement("UPDATE Sales.Customer SET PersonID = ? WHERE CustomerID = ?");

            ps.setInt(1, productId);
            ps.setInt(2, customerId);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    });
} catch (Exception e) {
    throw new StoreException(e.getMessage(), e);
}
int customerId = 12345;
int newPersonId = 4321;

Configuration.SqlRetryPolicy.ExecuteAction(() -> {

    // Connect to the shard for a customer ID.
    using (SqlConnection conn = customerShardMap.OpenConnectionForKey(customerId, Configuration.GetCredentialsConnectionString(), ConnectionOptions.Validate))
    {
        // Execute a simple command
        SqlCommand cmd = conn.CreateCommand();

        cmd.CommandText = @"UPDATE Sales.Customer
                            SET PersonID = @newPersonID
                            WHERE CustomerID = @customerID";

        cmd.Parameters.AddWithValue("@customerID", customerId);
        cmd.Parameters.AddWithValue("@newPersonID", newPersonId);
        cmd.ExecuteNonQuery();

        Console.WriteLine("Update completed");
    }
});

Balíčky potřebné k implementaci zpracování přechodných chyb se stáhnou automaticky při sestavování ukázkové aplikace elastické databáze.

Transakční konzistence

Transakční vlastnosti jsou zaručeny pro všechny operace místní do horizontálního oddílu. Například transakce odeslané prostřednictvím směrování závislého na datech se provádějí v rámci rozsahu cílového horizontálního oddílu pro připojení. V tuto chvíli nejsou k dispozici žádné možnosti pro zařazení více připojení do transakce, a proto neexistují žádné transakční záruky pro operace prováděné napříč horizontálními oddíly.

Další kroky

Pokud chcete odpojit horizontální oddíl nebo znovu připojit horizontální oddíl, přečtěte si téma Použití třídy RecoveryManager k řešení problémů s mapováním horizontálních oddílů.

Ještě nepoužíváte nástroje elastické databáze? Podívejte se na naši příručku Začínáme. Pokud máte dotazy, kontaktujte nás na stránce otázek Microsoft Q&A pro SLUŽBU SQL Database a žádosti o funkce, přidejte nové nápady nebo hlasujte pro stávající nápady ve fóru pro zpětnou vazbu ke službě SQL Database.