SQL Server verbindingspooling met Microsoft. Data.SqlClient

Microsoft. Data.Sql Client verbindingspooling hergebruikt geauthenticeerde fysieke verbindingen. SqlConnection.Open Of OpenAsync controleert een pool op een bruikbare verbinding. Close, Dispose, of DisposeAsync reset en geeft het terug. Deze aanpak voorkomt een netwerkverbinding, authenticatie en sessie-opstelling voor elke operatie.

Pooling is standaard ingeschakeld. Gebruik dit toepassingspatroon:

await using var connection = new SqlConnection(connectionString);
await connection.OpenAsync(cancellationToken);

using var command = new SqlCommand(sql, connection);
await command.ExecuteNonQueryAsync(cancellationToken);

Open pas laat, sluit vroeg en laat de pool de fysieke verbindingen beheren. Houd SqlConnection niet globaal open.

Kies een implementatie van een verbindingspool

SqlClient bevat twee implementaties voor verbindingspools. De V1-pool is de standaard. Vanaf Microsoft.Data.SqlClient 7.1 kun je je aanmelden voor de kanaalgebaseerde V2-pool door de Switch.Microsoft.Data.SqlClient.UseConnectionPoolV2 AppContext-schakelaar in te stellen op true bij het opstarten van de applicatie:

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseConnectionPoolV2", true);

Controles voor connection string pooling zijn van toepassing op beide implementaties. Voor meer informatie over de switch en de standaardinstelling ervan, zie De V2-verbindingspool inschakelen.

Begrijp poolsleutels

Een verbinding kan alleen opnieuw worden gebruikt vanuit de overeenkomende pool. De poolsleutel bevat meer dan alleen de bestemmingsserver.

Input poolgedrag
Verbindingsstring De tekst moet exact overeenkomen. Verschillen in trefwoordvolgorde creëren aparte pools, zelfs als de effectieve instellingen gelijk zijn.
Geïntegreerde Windows-verificatie De Windows-identiteit maakt deel uit van de sleutel. Dezelfde string die onder verschillende identiteiten wordt gebruikt, creëert verschillende pools.
SqlCredential De objectinstantie maakt deel uit van de sleutel. Aparte instanties creëren aparte pools, zelfs als ze dezelfde gebruikersnaam en wachtwoord bevatten.
SqlConnection.AccessToken De waarde van de toegangstoken maakt deel uit van de sleutel. Het vervangen van tokenreeksen kan nieuwe pools aanmaken, waardoor verbindingen in bestaande pools geverifieerd blijven met oude tokens.
SqlConnection.AccessTokenCallback De callbackfunctie maakt deel uit van de sleutel. Hergebruik dezelfde callback-instantie voor verbindingen die een pool zouden moeten delen. De teruggegeven tokenwaarde is niet de poolsleutel.
Aangepaste SSPI-contextprovider De provider-instantie neemt deel aan de verbindingsconfiguratie. Hergebruik één providerinstantie voor verbindingen die dezelfde pool moeten delen.
Omgevingstransactie Enlisted connections gebruiken transactie-specifieke onderverdelingen binnen de matching pool.

De database, authenticatiemodus, encryptie-opties, applicatienaam, poolingopties en alle andere waarden van de verbindingsreeks dragen bij via exact dezelfde string.

Bouw één canonieke verbindingsreeks en hergebruik die. Vermijd per-request waarden in Application Name, Workstation ID, of andere trefwoorden.

Kies token-API's die kunnen poolen

Voor Microsoft Entra ID-toegangstokens gebruik je een authenticatiemodus die door Microsoft.Data.SqlClient wordt geleverd of een stabiele AccessTokenCallback.

AccessTokenCallbackwerd geïntroduceerd in Microsoft. Data.SqlClient 5.2. De driver roept het aan wanneer het een token nodig heeft en kan een vernieuwde token aanvragen voor een hergebruikte pool. Zorg dat de callback deterministisch blijft voor de authenticatieparameters die door de driver worden geleverd, en hergebruik dezelfde delegate-instantie.

Wanneer code AccessToken direct instelt:

  • De tokenstring wordt onderdeel van de poolsleutel.
  • De applicatie beheert het verlopen en vernieuwen van tokens.
  • Een gepoolde fysieke verbinding kan langer meegaan dan het token dat is gebruikt om het te creëren.
  • Bel ClearPool na het vervangen van een verlopen token als die pool niet meer veilig gebruikt kan worden.

Maak niet voor elk verzoek een nieuwe callback lambda of credential-object. Verschillen in objectidentiteit kunnen de pools fragmenteren.

Microsoft. Data.SqlClient 7.0 voegt toe SspiContextProvider voor aangepaste Kerberos- of NTLM-onderhandeling. Behandel de provider als verbindingsconfiguratie op toepassingsniveau, niet als toestand per aanvraag.

Grootte van elke pool

Deze verbindingsreeks-opties beheren één pool. Voor de volledige trefwoordreferentie, zie ConnectionString.

Keyword Default Effect
Pooling true Schakelt pooling in of uit.
Min Pool Size 0 Stelt het minimale aantal fysieke verbindingen vast dat de pool behoudt nadat deze is aangemaakt.
Max Pool Size 100 Stelt het maximale aantal fysieke verbindingen in de pool in.
Connect Timeout 15 seconden Bepaalt hoe lang Open de wachttijd is wanneer er geen bruikbare verbinding beschikbaar is.
Load Balance Timeout 0 Seconden Verwijder een verbinding wanneer deze terugkeert naar de pool als de leeftijd de geconfigureerde waarde overschrijdt. Connection Lifetime is een alias.
Connection Idle Timeout 300 Vanaf versie 7.1.0 komt een inactieve verbinding na dit aantal seconden in aanmerking voor verwijdering. Een waarde van 0 schakelt de idle expiration uit. Handhaving vereist dat de UseLegacyIdleTimeoutBehavior AppContext-schakelaar ingeschakeld false.

De pool maakt verbindingen aan naarmate de vraag toeneemt totdat Max Pool Size is bereikt. Wanneer alle verbindingen in gebruik zijn, wachten latere verbindingspogingen tot er weer een verbinding beschikbaar komt. Als de wachttijd langer is dan Connect Timeout, mislukt de open.

Verhoog Max Pool Size niet voordat je het controleert:

  • Elke verbinding en lezer is op elk pad geplaatst.
  • Commando's en transacties worden snel afgerond.
  • De query-werklast is niet geblokkeerd of verzadigd.
  • De limiet van de databaseverbindingen moet Max Pool Size vermenigvuldigd met elke pool in elke applicatie-instantie aankunnen.

Een positieve Min Pool Size houdt de verbindingen open tijdens inactieve perioden. Gebruik het alleen wanneer de metingen warme verbindingen rechtvaardigen. Het werkt meestal tegen schaal-tot-nul, serverloze automatische pauze en burstbare cloudontwerpen.

Bij de standaard Load Balance Timeout=0verwijdert periodieke schoonmaak meestal ongebruikte verbindingen boven Min Pool Size ongeveer vier tot acht minuten, of verwijdert de pool ze zodra het detecteert dat de serververbinding verbroken is. Behandel dat interval als implementatiegedrag, niet als een idle-garantie per verbinding. De pool stuurt geen validatiequery voor elke afrekensessie omdat die retour veel van het poolingvoordeel wegneemt.

Beperk de inactiviteitsduur van de verbinding

Vanaf Microsoft.Data.SqlClient 7.1.0, gebruik Connection Idle Timeout om idle-expiry controles en achtergrondopruiming voor gepoolde verbindingen te configureren. De standaardwaarde is 300 seconden. Een waarde van 0 schakelt de idle expiration uit. Negatieve waarden genereren een ArgumentException.

Connection Idle Timeout=120

Je kunt SqlConnectionStringBuilder.IdleTimeout ook instellen wanneer je de verbindingsreeks bouwt:

var builder = new SqlConnectionStringBuilder(connectionString)
{
    IdleTimeout = 120
};

Handhaving van de idle-time-out moet expliciet worden ingeschakeld. Stel de volgende AppContext-schakelaar in op false bij het opstarten van de applicatie:

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseLegacyIdleTimeoutBehavior", false);

De switch en verbindingsreeks-instelling beïnvloeden elke pool-implementatie anders:

  • V1-pool. Wanneer de schakelaar is true, gebruikt V1 zijn historisch gerandomiseerde opruimcadans van twee tot vier minuten en verwijdert idle verbindingen ongeacht Connection Idle Timeout. Wanneer de schakelaar false staat en Connection Idle Timeout niet nul is, gebruikt V1 de helft van de geconfigureerde timeout als opruimingscadans en verwijdert hij de inactieve verbindingen na één of twee opruimcycli. Wanneer de schakelaar Connection Idle Timeout=0 en false is, schakelt V1 de idle-verwijdering uit, maar zet het minimale pool-grootte onderhoud voort op het historische willekeurige interval van twee tot vier minuten.
  • V2-pool. Wanneer de schakelaar op true staat, voert V2 geen idle-age-controles per verbinding uit, maar een niet-nulwaarde voor Connection Idle Timeout schakelt achtergrondopschoning in en configureert deze. Wanneer de schakelaar Connection Idle Timeout is en false niet nul is, voert V2 per-verbinding idle-age-controles uit en configureert opschoning op de achtergrond op basis van de timeout. Wanneer de schakelaar Connection Idle Timeout=0aanfalse en Connection Idle Timeout=0uitfalse is, voert V2 geen idle-agecontroles of achtergrondsnoeiwerk per verbinding uit. V2 voert geen achtergrondsnoei uit wanneer Min Pool Size groter dan of gelijk aan Max Pool Sizeis.

Beide poolimplementaties verwijderen ook een verbinding als de pooler ontdekt dat de verbinding met de server is verbroken.

Beheer blokkeringsperiodes voor authenticatie

Na een authenticatietime-out of andere authenticatiemislukking kan de pool in een blokkeringsperiode terechtkomen. Tijdens die periode gooien overeenkomende openingspogingen de oorspronkelijke uitzondering opnieuw, zonder opnieuw een authenticatiepoging te doen.

De eerste blokperiode duurt vijf seconden. Na een nieuwe mislukking verdubbelt de periode tot één minuut.

Pool Blocking Period beheert dit gedrag:

Value Gedrag
Auto Maakt blokkering mogelijk voor gewone SQL Server-eindpunten en schakelt deze uit voor herkende Azure SQL-eindpuntachtervoegsels. Een vanity DNS-naam ontvangt mogelijk niet het Azure-gedrag.
AlwaysBlock Schakelt de blokkeringsperiode voor elk eindpunt in.
NeverBlock Schakelt de blokkeringsperiode uit.

Behoud Auto, tenzij het gemeten ontwerp voor nieuwe pogingen van de applicatie een andere keuze vereist. Het uitschakelen van de blokkeringsperiode kan een inloggegevens-, firewall- of storingsprobleem veranderen in een authenticatiestorm.

De blokkeringsperiode is los van configureerbare herkansingslogica. Een retry-provider die dezelfde pool opent tijdens een blokkeringsperiode ontvangt de gecachete uitzondering.

Beheer de verbindingslevensduur en het clearen

De pool verwijdert de getroffen pool automatisch wanneer een fatale fout wordt herkend, zoals een failover. De pool sluit de inactieve verbindingen en gooit uitgecheckte verbindingen weg zodra ze terugkomen.

Gebruik de opschoon-API's voor een bekende configuratie- of aanmeldgegevensgrens:

  • ClearPool maakt het zwembad dat bij één SqlConnection configuratie hoort.
  • ClearAllPoolsCleart elke Microsoft. Data.SqlClient-pool in het proces- of applicatiedomein.

De pool sluit inactieve verbindingen in een geleegde pool. De pool markeert verbindingen die momenteel in gebruik zijn, zodat ze worden verwijderd wanneer ze worden teruggegeven.

Het wissen van pools zorgt ervoor dat latere openingen fysieke inlogs uitvoeren. Gebruik het niet als periodiek onderhoud, algemene foutenbehandelaar of als vervanging voor het weggooien van verbindingen.

Load Balance Timeout zorgt voor geleidelijke leeftijdsgebaseerde verloop. Gebruik dit wanneer een implementatie of geclusterde service geleidelijk oude fysieke verbindingen moet kunnen loslaten. Controleer of de gekozen waarde geen overmatige harde verbindingen veroorzaakt.

Inzicht in transacties

Met Enlist=true, als standaard, meldt een verbinding die binnen System.Transactions.Transaction.Current geopend wordt automatisch in die transactie in.

Wanneer een bij een transactie geregistreerde verbinding wordt gesloten, plaatst de pool deze in een transactiespecifieke onderverdeling. Een latere opening binnen dezelfde transactie kan deze hergebruiken. De fysieke verbinding keert pas terug naar de algemene pool nadat de transactie is voltooid.

Langdurige of achtergelaten omgevings-transacties kunnen daarom:

  • Houd fysieke verbindingen buiten de algemene pool.
  • Verbruik poolcapaciteit nadat de logische verbinding is gesloten.
  • Houd de serververgrendelingen en de transactiestatus actief.

Houd transacties begrensd, voltooi ze expliciet en monitor stasisverbindingen. Stel alleen in Enlist=false wanneer de verbinding buiten een ambient transactie moet blijven.

Poolfragmentatie voorkomen

Poolfragmentatie creëert veel kleine pools in plaats van een paar herbruikbare pools. Veelvoorkomende oorzaken zijn onder andere:

  • Verschillen in de volgorde van sleutelwoorden of alias in verbindingsstrings.
  • Eén verbindingsreeks per klant, gebruiker, verzoek of database.
  • Geïntegreerde authenticatie onder veel Windows-identiteiten.
  • Nieuwe SqlCredential, callback voor toegangstoken of SSPI-providerinstanties per verzoek.
  • Direct access tokens die bij elke verversing veranderen.
  • Applicatienamen of werkstation-ID's met hoge kardinaliteit.

Normaliseer verbindingsstrings met SqlConnectionStringBuilder en centraliseer de aanmaak van verbindingen.

Als de applicatie opzettelijk verbinding maakt met veel databases of identiteiten, neem dan het resulterende poolaantal mee in capaciteitsplanning. Voer USE niet met een onbetrouwbare databasenaam om pools te laten inklappen. Database-isolatie, permissies, sessiestatus en gedrag bij het resetten van de pool moeten expliciet blijven.

Houd rekening met applicatierollen en sessiestatus

De pool reset de herbruikbare SQL Server-sessiestatus voordat een fysieke verbinding wordt toegewezen aan een andere logische verbinding. De applicatiecode zou nog steeds elke vereiste sessiestatus binnen de eenheid van werk moeten instellen.

SQL Server-toepassingsrollen die met sp_setapprole zijn geactiveerd, kunnen niet veilig worden gereset voor normale pooling. Geef voorkeur aan databasegebruikers, gesloten gebruikers, rollen, beveiliging op rijniveau of een ander autorisatieontwerp. Als een applicatierol onvermijdelijk is, gebruik dan een gedocumenteerd cookie-gebaseerd omkeerpatroon of schakel na het testen de pooling voor dat geïsoleerde pad uit.

Verwijder lezers, voltooi of rol transacties terug, en laat geen commando's draaien wanneer de verbinding wordt gesloten. Vertrouw er niet op dat tijdelijke tabellen of andere sessietoestanden overleven over logische verbindingen.

Gebruik in de cloud gehoste poolingpatronen

Voor Azure App Service, Azure Functions, containers, Kubernetes en andere horizontaal geschaalde hosts:

  • Bereken de mogelijke databaseverbindingen over alle instanties, processen, poolsleutels en replica's.
  • Gebruik een managed identity of een callback voor een stabiel toegangstoken in plaats van roulerende tokenreeksen in verbindingsobjecten.
  • Behoud Min Pool Size=0 tenzij een gematigde cold-start vereiste het behouden van sessies rechtvaardigt.
  • Ga ervan uit dat een nieuwe instantie start met een lege pool.
  • Houd verbindingsstrings identiek tussen instanties die dezelfde werklast bedienen.
  • Beperk verbindingspogingen en nieuwe pogingen om gesynchroniseerde aanmeldpieken te voorkomen tijdens failover of scale-out.
  • Stel MultiSubnetFailover=true in voor Azure SQL en andere ondersteunde TCP-eindpunten met meerdere adressen.

Verbindingspools zijn lokaal binnen het aanvraagproces. Ze worden niet gedeeld tussen applicatie-instanties, containers of hosts.

Diagnoseer het gedrag van de pool

Gebruik SqlClient diagnostische tellers om te observeren:

  • Harde verbindingen en verbrekingen, die staan voor fysieke serververbindingen.
  • Soft connects en disconnects, die het uitchecken en terugkeren van de pool vertegenwoordigen.
  • Actieve en gratis gepoolde verbindingen.
  • Actieve poolgroepen en zwembaden.
  • Stasisverbindingen.
  • Teruggewonnen verbindingen waarbij applicatiecode de logische verbinding niet verwijderde.

Correleer clienttellers met SQL Server-sessies, wachttijden, blokkeringen en resourcelimieten. Een pool-timeout kan leiden tot een verbindingslek, trage queries, geblokkeerde transacties, te veel gelijktijdigheid, poolfragmentatie of een limiet op de databasecapaciteit.

Gebruik tracering van gebeurtenisbronnen voor gerichte traceringen van de pooler. Traceren is omvangrijk. Schakel het in voor een begrensd diagnostisch venster en bescherm alle vastgelegde verbindingsmetadata.

Controlelijst voor productie

  • Houd pooling ingeschakeld.
  • Hergebruik één canonieke verbindingsreeks per workload en database.
  • Verwijder verbindingen, commando's, lezers en transacties op elk pad.
  • Hergebruik van inloggegevens, token callback en SSPI-providerinstanties.
  • Stel beperkte time-outs voor verbindingen en opdrachten in.
  • Bepaal het totale verbindingsbudget voor elke applicatieinstantie.
  • Monitor harde verbindingen, pooltellingen, vrije verbindingen, stasis en time-outs.
  • Maak pools alleen schoon voor een credential, token of configuratiegrens die de provider niet kan detecteren, of wanneer diagnostiek bevestigt dat de verbindingen verouderd blijven.
  • Laadtest schaal-uit, failover en het verversen van de inloggegevens vóór de productie.