Sdružování připojení SQL Serveru (ADO.NET)

Připojení k databázovému serveru se obvykle skládá z několika časově náročných kroků. Je třeba navázat fyzický kanál, jako je soket nebo pojmenovaný kanál, musí nastat počáteční handshake se serverem, připojovací řetězec informace musí být analyzovány, připojení musí být ověřeno serverem, kontroly musí být spuštěny pro zařazení do aktuální transakce atd.

Většina aplikací v praxi používá pro připojení jenom jednu nebo několik různých konfigurací. To znamená, že během provádění aplikace se bude opakovaně otevírat a zavírat mnoho identických připojení. Aby se minimalizovaly náklady na otevírání připojení, ADO.NET používá metodu optimalizace označovanou jako sdružování připojení.

Sdružování připojení snižuje počet otevření nových připojení. Fond udržuje vlastnictví fyzického připojení. Spravuje připojení tím, že udržuje aktivní sadu aktivních připojení pro každou danou konfiguraci připojení. Pokaždé, když uživatel volá Open připojení, nástroj pro sdružování vyhledá dostupné připojení ve fondu. Pokud je připojení ve fondu k dispozici, vrátí se volajícímu místo otevření nového připojení. Když aplikace volá Close připojení, vrátí ji pooler do skupiny aktivních připojení místo jeho zavření. Jakmile se připojení vrátí do fondu, je připraveno k opětovnému použití při dalším Open volání.

Ve fondu se dají připojit pouze připojení se stejnou konfigurací. ADO.NET udržuje několik fondů najednou, jeden pro každou konfiguraci. Připojení jsou oddělená do fondů pomocí připojovací řetězec a identita Systému Windows při použití integrovaného zabezpečení. Připojení jsou také ve fondu na základě toho, zda jsou zařazeny do transakce. Při použití ChangePasswordSqlCredential má instance vliv na fond připojení. Různé instance SqlCredential budou používat různé fondy připojení, i když id uživatele a heslo jsou stejné.

Sdružování připojení může výrazně zvýšit výkon a škálovatelnost vaší aplikace. Ve výchozím nastavení je ve ADO.NET povolené sdružování připojení. Pokud ho explicitně nezakážete, nástroj pro sdružování optimalizuje připojení při jejich otevření a zavření ve vaší aplikaci. Můžete také zadat několik modifikátorů připojovací řetězec pro řízení chování sdružování připojení. Další informace najdete v části Řízení sdružování připojení pomocí klíčových slov připojovacího řetězce dále v tomto tématu.

Poznámka:

Pokud je povolené sdružování připojení a pokud dojde k chybě vypršení časového limitu nebo jiné chyby přihlášení, vyvolá se výjimka a následné pokusy o připojení se na dalších pět sekund nezdaří, "blokující období". Pokud se aplikace pokusí připojit v době blokování, vyvolá se první výjimka znovu. Následná selhání po skončení blokujícího období budou mít za následek nová období blokování, která jsou dvojnásobná, pokud je předchozí blokovací období až do jedné minuty.

Vytvoření a přiřazení fondu

Při prvním otevření připojení se vytvoří fond připojení na základě přesného odpovídajícího algoritmu, který přidruží fond k připojovací řetězec v připojení. Každý fond připojení je přidružený k odlišnému připojovací řetězec. Pokud se otevře nové připojení, připojovací řetězec není přesná shoda s existujícím fondem, vytvoří se nový fond. Připojení jsou ve fondu podle procesu, na doménu aplikace, na připojovací řetězec a při použití integrovaného zabezpečení na identitu Systému Windows. Připojovací řetězce musí být také přesnou shodou; Klíčová slova zadaná v jiném pořadí pro stejné připojení budou ve fondu oddělena.

V následujícím příkladu jazyka C# se vytvoří tři nové SqlConnection objekty, ale ke správě je potřeba jenom dva fondy připojení. Všimněte si, že první a druhý připojovací řetězec se liší podle hodnoty přiřazené .Initial Catalog

using (SqlConnection connection = new SqlConnection(
  "Integrated Security=SSPI;Initial Catalog=Northwind"))
    {
        connection.Open();
        // Pool A is created.
    }

using (SqlConnection connection = new SqlConnection(
  "Integrated Security=SSPI;Initial Catalog=pubs"))
    {
        connection.Open();
        // Pool B is created because the connection strings differ.
    }

using (SqlConnection connection = new SqlConnection(
  "Integrated Security=SSPI;Initial Catalog=Northwind"))
    {
        connection.Open();
        // The connection string matches pool A.
    }

Důležité

Microsoft doporučuje používat nejbezpečnější dostupný tok ověřování. Pokud se připojujete k Azure SQL, spravované identity pro prostředky Azure se doporučují metodou ověřování.

Pokud Min Pool Size není v připojovací řetězec zadána nebo je zadána jako nula, připojení ve fondu budou uzavřena po určité době nečinnosti. Pokud je však zadaná Min Pool Size hodnota větší než nula, fond připojení se nezničí, dokud AppDomain se nenačte a proces skončí. Údržba neaktivních nebo prázdných fondů zahrnuje minimální systémové režie.

Poznámka:

Fond se automaticky vymaže, když dojde k závažné chybě, například převzetí služeb při selhání.

Přidání připojení

Pro každý jedinečný připojovací řetězec se vytvoří fond připojení. Při vytvoření fondu se vytvoří a přidá do fondu více objektů připojení, aby byl splněn požadavek na minimální velikost fondu. Podle potřeby se do fondu přidají připojení až do maximální velikosti fondu (výchozí hodnota je 100). Připojení se uvolní zpět do fondu, když jsou zavřená nebo uvolněná.

SqlConnection Pokud je objekt požadován, získá se z fondu, pokud je k dispozici použitelné připojení. Aby bylo možné použít připojení, musí být nepoužité, musí mít odpovídající kontext transakce nebo být nepřidružen k libovolnému kontextu transakce a mít platný odkaz na server.

Fond připojení splňuje požadavky na připojení tím, že při jejich uvolnění zpět do fondu uvolní připojení. Pokud byla dosažena maximální velikost fondu a není k dispozici žádné použitelné připojení, žádost se zařadí do fronty. Fond se pak pokusí uvolnit všechna připojení, dokud nedojde k vypršení časového limitu (výchozí hodnota je 15 sekund). Pokud fond nemůže požadavek splnit před vypršením časového limitu připojení, vyvolá se výjimka.

Upozornění

Důrazně doporučujeme, abyste připojení vždy zavřeli, až ho použijete, aby se připojení vrátilo do fondu. Můžete to provést buď pomocí Close nebo Dispose metod objektu Connection , nebo otevřením všech připojení uvnitř using příkazu v jazyce C# nebo Using příkazem v jazyce Visual Basic. Připojení, která nejsou explicitně uzavřená, nemusí být přidána nebo vrácena do fondu. Další informace naleznete v tématu using příkaz nebo Postupy: Dispose of a System Resource for Visual Basic.

Poznámka:

Nevyvolávejte ani nezavolávejte Close Connection, DataReadernebo Dispose žádný jiný spravovaný objekt v Finalize metodě třídy. V finalizátoru uvolněte pouze nespravované prostředky, které vaše třída vlastní přímo. Pokud vaše třída nevlastní žádné nespravované prostředky, nezahrnujte do definice třídy metodu Finalize . Další informace naleznete v tématu Uvolňování paměti.

Další informace o událostech přidružených k otevírání a zavírání připojení najdete v tématu Audit Login Event Class and Audit Logout Event Class in the SQL Server documentation.

Odebrání připojení

Nástroj pro sdružování připojení odebere připojení z fondu po dobu přibližně 4 až 8 minut nečinnosti nebo pokud nástroj pro sdružování zjistí, že připojení k serveru bylo přerušeno. Všimněte si, že přerušené připojení lze zjistit až po pokusu o komunikaci se serverem. Pokud se najde připojení, které už není připojené k serveru, označí se jako neplatné. Neplatná připojení se z fondu připojení odeberou jenom v případech, kdy jsou uzavřená nebo uvolněná.

Pokud existuje připojení k serveru, který zmizel, je možné toto připojení nakreslit z fondu i v případě, že nástroj pro sdružování připojení nezjistil přerušené připojení a označil ho jako neplatné. Důvodem je, že režie při kontrole, že připojení je stále platné, by eliminovala výhody sdružování tím, že by způsobila další odezvu na server. Když k tomu dojde, první pokus o použití připojení zjistí, že připojení bylo přerušeno a vyvolá se výjimka.

Vymazání fondu

ADO.NET 2.0 zavedl dvě nové metody pro vymazání fondu: ClearAllPools a ClearPool. ClearAllPools vymaže fondy připojení pro daného poskytovatele a ClearPool vymaže fond připojení přidružený ke konkrétnímu připojení. Pokud se v době volání používají připojení, označí se odpovídajícím způsobem. Po zavření se místo vrácení do fondu zahodí.

Podpora transakcí

Připojení se načítají z fondu a přiřazují se na základě kontextu transakce. Pokud Enlist=false není uvedeno v připojovací řetězec, fond připojení zajistí, že je připojení zařazeno do Current kontextu. Pokud je připojení uzavřeno a vráceno do fondu se zařazením System.Transactions transakce, je vyhrazeno takovým způsobem, že další požadavek na tento fond připojení se stejnou System.Transactions transakcí vrátí stejné připojení, pokud je k dispozici. Pokud je taková žádost vydána a nejsou k dispozici žádná připojení ve fondu, je připojení odebráno z neprovedené části fondu a zařazeno. Pokud nejsou v žádné oblasti fondu k dispozici žádná připojení, vytvoří se nové připojení a připojí se.

Když je připojení uzavřeno, uvolní se zpět do fondu a do příslušného dílčího dělení na základě jeho kontextu transakce. Připojení proto můžete zavřít bez generování chyby, i když distribuovaná transakce stále čeká na vyřízení. To vám umožní potvrdit nebo přerušit distribuovanou transakci později.

Řízení sdružování připojení pomocí klíčových slov připojovací řetězec

ConnectionString Vlastnost objektu SqlConnection podporuje připojovací řetězec páry klíč/hodnota, které lze použít k úpravě chování logiky sdružování připojení. Další informace najdete na webu ConnectionString.

Fragmentace fondu

Fragmentace fondu je běžným problémem v mnoha webových aplikacích, kde může aplikace vytvořit velký počet fondů, které nejsou uvolněny, dokud proces neodejde. Díky tomu je velký počet připojení otevřený a spotřeba paměti, což vede k nízkému výkonu.

Fragmentace fondu z důvodu integrovaného zabezpečení

Připojení jsou ve fondu podle připojovací řetězec plus identita uživatele. Proto pokud používáte základní ověřování nebo ověřování systému Windows na webu a integrované přihlášení zabezpečení, získáte jeden fond na uživatele. I když se tím zlepší výkon následných žádostí o databázi pro jednoho uživatele, nemůže tento uživatel využívat připojení provedená jinými uživateli. Výsledkem je také alespoň jedno připojení na uživatele k databázovému serveru. Jedná se o vedlejší účinek konkrétní architektury webových aplikací, kterou musí vývojáři zvážit s požadavky na zabezpečení a auditování.

Fragmentace fondu kvůli mnoha databázím

Mnoho poskytovatelů internetových služeb hostuje několik webů na jednom serveru. Můžou použít jednoúčelovou databázi k potvrzení přihlášení pomocí formulářů a pak otevřít připojení ke konkrétní databázi pro daného uživatele nebo skupinu uživatelů. Připojení k ověřovací databázi je ve fondu a používá ho všichni. Existuje však samostatný fond připojení k jednotlivým databázím, které zvyšují počet připojení k serveru.

Jedná se také o vedlejší účinek návrhu aplikace. Existuje poměrně jednoduchý způsob, jak se vyhnout tomuto vedlejšímu efektu, aniž byste museli ohrozit zabezpečení při připojování k SQL Serveru. Místo připojení k samostatné databázi pro každého uživatele nebo skupiny se připojte ke stejné databázi na serveru a pak spusťte příkaz Transact-SQL USE, který se změní na požadovanou databázi. Následující fragment kódu ukazuje vytvoření počátečního připojení k master databázi a následné přepnutí na požadovanou databázi zadanou databaseName v řetězcové proměnné.

' Assumes that command is a SqlCommand object.
command.Text = "USE DatabaseName"
Using connection As New SqlConnection(connectionString)
    connection.Open()
    command.ExecuteNonQuery()
End Using
// Assumes that command is a SqlCommand object.
command.Text = "USE DatabaseName";
using (SqlConnection connection = new SqlConnection(
  connectionString))
  {
    connection.Open();
    command.ExecuteNonQuery();
  }

Role aplikací a sdružování připojení

Po aktivaci role aplikace SYSTÉMU SQL Server voláním sp_setapprole uložené procedury systému nelze obnovit kontext zabezpečení tohoto připojení. Pokud je však sdružování povolené, připojení se vrátí do fondu a při opětovném použití fondu dojde k chybě.

Viz také