Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Van toepassing op: .NET Framework
.NET
Standard
Verbinding maken met een databaseserver bestaat doorgaans uit verschillende tijdrovende stappen. Een fysiek kanaal, zoals een socket of een benoemde pijp, moet tot stand worden gebracht, de eerste handshake met de server moet plaatsvinden, de gegevens van de verbindingsreeks moeten worden geparseerd, de verbinding moet worden geverifieerd door de server, er moeten controles worden uitgevoerd om in te schakelen in de huidige transactie, enzovoort.
In de praktijk gebruiken de meeste toepassingen slechts één of enkele verschillende configuraties voor verbindingen. Dit betekent dat tijdens het uitvoeren van de toepassing veel identieke verbindingen herhaaldelijk worden geopend en gesloten. Om de kosten van het openen van verbindingen te minimaliseren, maakt Microsoft SqlClient Data Provider voor SQL Server gebruik van een optimalisatietechniek die verbindingspooling wordt genoemd.
Het groeperen van verbindingen vermindert het aantal keren dat nieuwe verbindingen moeten worden geopend. De pooler behoudt het eigendom van de fysieke verbinding. Het beheert verbindingen door een set actieve verbindingen in leven te houden voor elke opgegeven verbindingsconfiguratie. Wanneer een gebruiker een verbinding aanroept Open , zoekt de pooler naar een beschikbare verbinding in de pool. Als er een gegroepeerde verbinding beschikbaar is, wordt deze teruggezet naar de beller in plaats van een nieuwe verbinding te openen. Wanneer de toepassing de verbinding aanroept, retourneert Close de pooler deze naar de gegroepeerde set actieve verbindingen in plaats van deze te sluiten. Zodra de verbinding naar de pool is geretourneerd, is deze klaar om opnieuw te worden gebruikt bij de volgende Open aanroep.
Alleen verbindingen met dezelfde configuratie kunnen worden gegroepeerd. Microsoft SqlClient Data Provider voor SQL Server bewaart meerdere pools tegelijk, één voor elke configuratie. Verbindingen worden gescheiden in pools per verbindingsreeks en door Windows-identiteit wanneer geïntegreerde beveiliging wordt gebruikt. Verbindingen worden ook gegroepeerd op basis van of ze zijn opgenomen in een transactie. Wanneer u ChangePassword gebruikt, is het SqlCredential exemplaar van invloed op de verbindingenpool. Verschillende exemplaren van SqlCredential zullen verschillende verbindingsgroepen gebruiken, zelfs als de gebruikers-id en het wachtwoord hetzelfde zijn.
Het groeperen van verbindingen kan de prestaties en schaalbaarheid van uw toepassing aanzienlijk verbeteren. Standaard is groepsgewijze verbinding ingeschakeld in de Microsoft SqlClient-gegevensprovider voor SQL Server. Tenzij u deze expliciet uitschakelt, optimaliseert de pooler de verbindingen zodra deze worden geopend en gesloten in uw toepassing. U kunt ook verschillende verbindingsreeksaanpassingen opgeven om het gedrag van verbindingsgroepen te beheren. Zie 'Verbindingsgroepen beheren met trefwoorden voor verbindingsreeksen' verderop in dit onderwerp voor meer informatie.
Belangrijk
Wanneer groepsgewijze verbindingen is ingeschakeld en er een time-outfout of een andere aanmeldingsfout optreedt, wordt er een uitzondering gegenereerd en mislukken volgende verbindingspogingen voor de komende vijf seconden, de 'blocking period'. Als de toepassing probeert verbinding te maken binnen de blokkeringsperiode, wordt de eerste uitzondering opnieuw gegenereerd. Volgende fouten na een blokkeringsperiode leiden tot een nieuwe blokkeringsperiode die twee keer zo lang is als de vorige blokkeringsperiode, tot maximaal 1 minuut.
Opmerking
Het mechanisme 'blocking period' is standaard niet van toepassing op Azure SQL Server. Dit gedrag kan worden veranderd door de PoolBlockingPeriod eigenschap te wijzigen in ConnectionString, met uitzondering van .NET Standard.
Pool maken en toewijzen
Wanneer een verbinding voor het eerst wordt geopend, wordt er een verbindingsgroep gemaakt op basis van een exact overeenkomend algoritme dat de pool koppelt aan de verbindingsreeks in de verbinding. Elke verbindingsgroep is gekoppeld aan een afzonderlijke verbindingsreeks. Wanneer een nieuwe verbinding wordt geopend, wordt er een nieuwe pool gemaakt als de verbindingsreeks niet exact overeenkomt met een bestaande pool.
Opmerking
Verbindingen worden gegroepeerd per proces, per toepassingsdomein, per verbindingsreeks en wanneer geïntegreerde beveiliging wordt gebruikt, per Windows-identiteit. Verbindingsreeksen moeten ook een exacte overeenkomst zijn; trefwoorden die in een andere volgorde voor dezelfde verbinding worden opgegeven, worden afzonderlijk gegroepeerd.
Opmerking
Als MinPoolSize niet is opgegeven in de verbindingsreeks of is ingesteld op nul, worden de verbindingen in de pool gesloten bij inactiviteit. Als de opgegeven MinPoolSize waarde echter groter is dan nul, wordt de verbindingsgroep pas vernietigd nadat de AppDomain verbinding is uitgepakt en het proces wordt beëindigd. Onderhoud van inactieve of lege pools omvat minimale systeemoverhead.
Opmerking
De pool wordt automatisch gewist wanneer er een fatale fout optreedt, zoals een failover.
In het volgende C#-voorbeeld worden drie nieuwe SqlConnection objecten gemaakt, maar er zijn slechts twee verbindingsgroepen vereist om ze te beheren. Houd er rekening mee dat de eerste en tweede verbindingsreeksen verschillen met de waarde die is toegewezen voor 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.
}
Verbindingen toevoegen
Er wordt een verbindingsgroep gemaakt voor elke unieke verbindingsreeks. Wanneer een pool wordt gemaakt, worden er meerdere verbindingsobjecten gemaakt en toegevoegd aan de pool, zodat aan de minimale grootte van de pool wordt voldaan. Verbindingen worden indien nodig aan de pool toegevoegd, tot de maximale grootte van de opgegeven pool (100 is de standaardgrootte). Verbindingen worden teruggegeven aan de pool wanneer ze worden gesloten of opgeruimd.
Wanneer een SqlConnection object wordt aangevraagd, wordt het verkregen uit de pool als er een bruikbare verbinding beschikbaar is. Om bruikbaar te zijn, moet een verbinding ongebruikt zijn, een overeenkomende transactiecontext hebben of niet zijn gekoppeld aan een transactiecontext en een geldige koppeling hebben naar de server.
De verbindingspooler voldoet aan aanvragen voor verbindingen door verbindingen opnieuw te verplaatsen naarmate ze weer in de pool worden vrijgegeven. Als de maximale poolgrootte is bereikt en er geen bruikbare verbinding beschikbaar is, wordt de aanvraag in de wachtrij geplaatst. De pooler probeert vervolgens verbindingen vrij te maken totdat de time-out is bereikt (de standaardwaarde is 15 seconden). Als de pooler niet aan de aanvraag kan voldoen voordat er een time-out optreedt voor de verbinding, wordt er een uitzondering gegenereerd.
Waarschuwing
We raden u ten zeerste aan de verbinding altijd te sluiten wanneer u klaar bent met het gebruik, zodat de verbinding wordt geretourneerd naar de pool. U kunt dit doen met behulp van de Close of Dispose methoden van het Connection object, of door alle verbindingen in een using instructie in C# of een Using instructie in Visual Basic te openen. Verbindingen die niet expliciet zijn gesloten, worden mogelijk niet toegevoegd of geretourneerd aan de pool. Zie voor meer informatie using-instructie of Hoe: een systeemresource verwijderen voor Visual Basic.
Opmerking
Roep in de Finalize methode van uw klasse niet Close of Dispose aan op een Connection, een DataReader, of enig ander beheerd object. In een finalizer kunt u alleen onbeheerde resources vrijgeven die rechtstreeks eigendom zijn van uw klasse. Als uw klasse geen onbeheerde resources bezit, neemt u Finalize geen methode op in uw klassedefinitie. Zie Garbagecollection voor meer informatie.
Zie Gebeurtenisklasse voor auditaanmelding en Gebeurtenisklasse voor auditafmelding in de documentatie van SQL Server voor meer informatie over de gebeurtenissen die zijn gekoppeld aan het openen en sluiten van verbindingen.
Verbindingen verwijderen
Als LoadBalanceTimeout (of Connection Lifetime) is ingesteld wanneer een verbinding wordt geretourneerd naar de pool, wordt de aanmaaktijd vergeleken met de huidige tijd en wordt de verbinding vernietigd als die tijdsduur (in seconden) de waarde overschrijdt die is opgegeven door LoadBalanceTimeout. Dit is handig in geclusterde configuraties om taakverdeling af te dwingen tussen een actieve server en een server die zojuist online is gebracht.
Als LoadBalanceTimeout (of levensduur van verbinding) niet is ingesteld (standaardwaarde = 0), verwijdert de verbindingspooler een verbinding uit de pool nadat deze ongeveer 4-8 minuten inactief is geweest (op willekeurige twee-pass-wijze) of als de pooler detecteert dat de verbinding met de server is verbroken.
Opmerking
Een verbroken verbinding kan alleen worden gedetecteerd nadat u hebt geprobeerd met de server te communiceren. Als er een verbinding wordt gevonden die niet meer is verbonden met de server, wordt deze gemarkeerd als ongeldig. Ongeldige verbindingen worden alleen uit de verbindingsgroep verwijderd wanneer ze worden gesloten of vrijgemaakt.
Als er een verbinding bestaat met een server die is verdwenen, kan deze verbinding worden getrokken uit de pool, zelfs als de verbindingspooler de verbroken verbinding niet heeft gedetecteerd en gemarkeerd als ongeldig. Dit is het geval omdat de overhead van het controleren of de verbinding nog steeds geldig is, de voordelen van het gebruik van een pooler elimineert door een extra verbindingscyclus met de server te veroorzaken. Wanneer dit gebeurt, wordt bij de eerste poging om de verbinding te gebruiken gedetecteerd dat de verbinding is verbroken en wordt er een uitzondering gegenereerd.
Het zwembad leegmaken
Microsoft SqlClient Data Provider voor SQL Server heeft twee nieuwe methoden geïntroduceerd om de pool te wissen: ClearAllPools en ClearPool.
ClearAllPools leegt de verbindingen voor een bepaalde provider en ClearPool leegt de verbinding die is gekoppeld aan een specifieke verbinding.
Opmerking
Als er verbindingen worden gebruikt op het moment van de oproep, worden ze op de juiste manier gemarkeerd. Wanneer ze gesloten zijn, worden ze verwijderd in plaats van terug te keren naar de pool.
Transactieondersteuning
Verbindingen worden opgehaald uit de pool en toegewezen op basis van transactiecontext. Tenzij Enlist=false is opgegeven in de verbindingsreeks, zorgt de connection pool ervoor dat de verbinding wordt opgenomen in de Current context. Wanneer een verbinding wordt gesloten en geretourneerd naar de pool met een geënliste transactie, wordt deze op een zodanige manier apart gezet dat de volgende aanvraag voor die verbindingspool met dezelfde transactie dezelfde verbinding retourneert als deze beschikbaar is. Als een dergelijk verzoek wordt uitgegeven en er geen gepoolde verbindingen beschikbaar zijn, wordt er een verbinding uit het niet-getransacteerde deel van de pool gehaald en geregistreerd. Als er geen verbindingen beschikbaar zijn in een van beide gebieden van de pool, wordt er een nieuwe verbinding gemaakt en in de lijst opgenomen.
Wanneer een verbinding wordt gesloten, wordt deze weer in de pool en in de juiste onderverdeling vrijgegeven op basis van de transactiecontext. Daarom kunt u de verbinding sluiten zonder een fout te genereren, ook al is een gedistribueerde transactie nog in behandeling. Hierdoor kunt u de gedistribueerde transactie later doorvoeren of afbreken.
Verbindingpooling beheren met verbindingsreeks-trefwoorden
De ConnectionString eigenschap van het SqlConnection object ondersteunt sleutel-/waardeparen voor verbindingsreeksen die kunnen worden gebruikt om het gedrag van de verbindingsgroeplogica aan te passen. Zie ConnectionString voor meer informatie.
Poolfragmentatie
Poolfragmentatie is een veelvoorkomend probleem in veel webtoepassingen waarbij de toepassing een groot aantal pools kan maken die niet worden vrijgemaakt totdat het proces wordt afgesloten. Hierdoor blijft een groot aantal verbindingen open en verbruikend geheugen, wat resulteert in slechte prestaties.
Poolfragmentatie vanwege geïntegreerde beveiliging
Verbindingen worden gegroepeerd op basis van de verbindingsreeks plus de gebruikersidentiteit. Als u basisverificatie of Windows-verificatie gebruikt op de website en een geïntegreerde beveiligingsaanmelding, krijgt u dus één groep per gebruiker. Hoewel dit de prestaties van volgende databaseaanvragen voor één gebruiker verbetert, kan die gebruiker niet profiteren van verbindingen die door andere gebruikers zijn gemaakt. Het resulteert ook in ten minste één verbinding per gebruiker met de databaseserver. Dit is een neveneffect van een bepaalde webtoepassingsarchitectuur die ontwikkelaars moeten afwegen tegen beveiligings- en controlevereisten.
Poolfragmentatie vanwege veel databases
Veel internetproviders hosten verschillende websites op één server. Ze kunnen één database gebruiken om een aanmelding bij formulierverificatie te bevestigen en vervolgens een verbinding te openen met een specifieke database voor die gebruiker of groep gebruikers. De verbinding met de verificatiedatabase wordt gegroepeerd en door iedereen gebruikt. Er is echter een afzonderlijke groep verbindingen met elke database, waardoor het aantal verbindingen met de server wordt verhoogd.
Dit is ook een neveneffect van het toepassingsontwerp. Er is een relatief eenvoudige manier om dit neveneffect te voorkomen zonder de beveiliging in gevaar te brengen wanneer u verbinding maakt met SQL Server. In plaats van verbinding te maken met een afzonderlijke database voor elke gebruiker of groep, maakt u verbinding met dezelfde database op de server en voert u de instructie Transact-SQL USE uit om naar de gewenste database te gaan.
Het volgende codefragment laat zien hoe u een eerste verbinding met de master database maakt en vervolgens overschakelt naar de gewenste database die is opgegeven in de databaseName tekenreeksvariabele.
// 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();
}
Toepassingsrollen en groepsgewijze verbindingen
Nadat een SQL Server-toepassingsrol is geactiveerd door het aanroepen van de sp_setapprole door het systeem opgeslagen procedure, kan de beveiligingscontext van die verbinding niet opnieuw worden ingesteld. Als pooling echter is ingeschakeld, wordt de verbinding teruggezet naar de pool en treedt er een fout op wanneer de poolverbinding opnieuw wordt gebruikt.
Alternatieven voor toepassingsrollen
U wordt aangeraden te profiteren van beveiligingsmechanismen die u kunt gebruiken in plaats van toepassingsrollen.