Sdílet prostřednictvím


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

Platí pro: .NET Framework .NET Standard

Stáhnout ADO.NET

Připojení k databázovému serveru se obvykle skládá z několika časově náročných kroků. Musí být vytvořen fyzický kanál, jako je soket nebo pojmenovaný kanál, musí dojít k počátečnímu handshake se serverem, musí být analyzovány informace o připojovacím řetězci, 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í, microsoft SqlClient Data Provider pro SQL Server 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í. Pooler 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í, správce spojení vyhledá dostupné připojení ve fondu. Pokud je připojení ve fondu k dispozici, je vráceno volajícímu namísto otevření nového připojení. Když aplikace volá na připojení pomocí Close, pooler jej vrátí do sady 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í.

Pouze připojení se stejnou konfigurací lze seskupovat do fondu. Zprostředkovatel dat Microsoft SqlClient pro SQL Server uchovává několik fondů současně, jeden pro každou konfiguraci. Připojení jsou oddělená do fondů podle připojovacího řetězce a identity systému Windows při použití integrovaného zabezpečení. Připojení jsou také seskupována na základě toho, zda jsou zařazeny do transakčního procesu. Při použití ChangePassword má instance SqlCredential 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 sdružování připojení povolené ve zprostředkovateli dat Microsoft SqlClient pro SQL Server. 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ího řetězce 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.

Důležité

Pokud je povolené sdružování připojení a 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 nezdaří po dobu následujících 5 sekund, tjblocking period. Pokud se aplikace pokusí připojit v době blokování, vyvolá se první výjimka znovu. Následná selhání po skončení blokovacího období budou mít za následek nová období blokování, která jsou dvakrát tak dlouhá jako předchozí blokovací období, maximálně do 1 minuty.

Poznámka:

Mechanismus "blocking period" se ve výchozím nastavení nevztahuje na Azure SQL Server. Toto chování lze změnit úpravou vlastnosti PoolBlockingPeriod v ConnectionString s výjimkou .NET Standard.

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

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ímu řetězci v připojení. Každý pool připojení je přidružený k samostatnému připojovacímu řetězci. Když se otevře nové připojení, vytvoří se nový fond, pokud se připojovací řetězec přesně neshoduje s existujícím fondem.

Poznámka:

Připojení jsou ve fondu pro jednotlivé procesy, podle domény aplikace, podle připojovacího řetězce a při použití integrovaného zabezpečení podle identity 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 samostatně zpracována.

Poznámka:

Pokud MinPoolSize není zadán v připojovacím řetězci nebo je zadán jako nula, připojení ve fondu budou uzavřena po určité době nečinnosti. Pokud je však zadaná MinPoolSize 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řepnutí při selhání.

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é pro 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.  
        }

Přidejte 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 vracejí do fondu, když jsou zavřená nebo zavržená.

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.

Správce fondu připojení splňuje požadavky na připojení tím, že připojení, která jsou uvolněna zpět do fondu, znovu přiděluje. Pokud byla dosažena maximální velikost fondu a není k dispozici žádné použitelné připojení, žádost bude zařazena 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 pooler 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 poté, co ho dokončíte používat, aby se 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. Podrobnosti naleznete v tématu Using Statement nebo Jak: Likvidace systémového prostředku pro Visual Basic.

Poznámka:

Nepoužívejte ani Close ani Dispose na Connection, DataReader nebo jakýkoli jiný spravovaný objekt v metodě Finalize vaší 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.

Odebrat připojení

Pokud je nastaven LoadBalanceTimeout (nebo Connection Lifetime), doba vytvoření připojení se při vrácení do fondu porovná s aktuálním časem a připojení se zničí, pokud toto časové rozpětí (v sekundách) překročí hodnotu určenou LoadBalanceTimeout. To je užitečné v clusterovaných konfiguracích k vynucení vyrovnávání zatížení mezi běžícím serverem a serverem, který jste právě převedli do režimu online.

Pokud není nastavena hodnota LoadBalanceTimeout (nebo Doba života připojení) (výchozí hodnota = 0), nástroj pro sdružování připojení odebere připojení z fondu po přibližně 4 až 8 minutách (metodou dvou průchodů), nebo pokud zjistí, že připojení k serveru bylo ukončeno.

Poznámka:

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, může být toto připojení odebráno z fondu i v případě, že nástroj pro sdružování připojení ještě nezaznamenal přerušené připojení a neoznačil ho jako neplatné. Důvodem je, že režie při kontrole, že připojení je stále platné, by eliminovala výhody použití pooleru tím, že by způsobila další kolečko 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.

Vyprázdnit fond

Zprostředkovatel dat Microsoft SqlClient pro SQL Server 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í.

Poznámka:

Pokud se v době volání používají připojení, označí se odpovídajícím způsobem. Po jejich zavření se místo vrácení do poolu zahodí.

Podpora transakcí

Připojení jsou čerpána z fondu a přiřazována na základě kontextu transakce. Pokud Enlist=false není zadán v připojovacím řetězci, fond propojení zajistí, že je spojení zařazeno do Current kontextu. Pokud je připojení uzavřeno a vráceno do fondu po zpracování System.Transactions transakce, je uchováno stranou tak, že při dalším požadavku na ten samý fond připojení se shodnou System.Transactions transakcí se vrátí stejné připojení, pokud je dostupné. 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 pododdělení podle 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.

Řiďte sdružování připojení pomocí klíčových slov v připojovacím řetězci

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

Fragmentace paměťového poolu

Fragmentace poolu je běžným problémem v mnoha webových aplikacích, kde může aplikace vytvořit velký počet poolů, které nejsou uvolněny, dokud proces neukončí. Otevření velkého počtu připojení a spotřeba paměti vede k špatnému výkonu.

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

Připojení jsou ve fondu podle připojovacího řetězce a identity uživatele. Proto, pokud používáte základní ověřování nebo ověřování systému Windows na webu, a integrované zabezpečené přihláš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 sdružováno a používají jej všichni uživatelé. Existuje však samostatný fond připojení ke každé databázi, což zvyšuje 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 potom spusťte příkaz Transact-SQL USE, aby se změnil 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é.

// Assume that connectionString connects to master.  
using (SqlConnection connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand())
{
    connection.Open();
    command.Connection = connection;
    command.CommandText = "USE DatabaseName";
    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í povoleno, připojení se vrátí do fondu a při opětovném použití sdruženého připojení dojde k chybě.

Alternativy aplikačních rolí

Doporučujeme využít mechanismy zabezpečení, které můžete použít místo aplikačních rolí.

Viz také