Tämä artikkeli on konekäännöksen peiliartikkeli, klikkaa tästä siirtyäksesi alkuperäiseen artikkeliin.

Näkymä: 24272|Vastaus: 0

[Lähde] EF Core -kuoppa: DbContextPool aiheuttaa tietokantayhteyspoolin yhteyden ehtymisen

[Kopioi linkki]
Julkaistu 2019-11-18 klo 14:41:59 | | |
DbContextPool on uusi ominaisuus, joka esiteltiin ASP.NET Core 2.1:ssä ja joka säästää DbContext-instanssin luomisen ylimääräistä kuormaa, mutta siihen on piilotettu pieni kuoppa.
Äskettäin ASP.NET Core -projekti pyöri yhtäjaksoisesti jonkin aikaa, ja lokeihin ilmestyi virhe, jonka mukaan tietokanta-yhteyspooli saavutti suurimman määrän yhteyksiä:


System.InvalidOperationException: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
   osoitteessa System.Data.Common.ADP.ExceptionWithStackTrace(Exception e)
Aluksi luulin, että kyseessä oli jokin koodi, joka sai DbContextin hävittämään sen oikein, mutta en löytänyt koodista mitään vihjeitä. Myöhemmin ei ollut mitään muuta epäiltävää, vain DbContextPool, joten yritin poistaa DbContextPoolin, mutta virhe katosi. Se johtui tosiaan DbContextPoolista, mutta mikä saa ihmiset ihmettelemään, on se, että DbContextPool on alun perin tarkoitettu säästämään DbContext-instanssien luomisen ylikuormaa, joten miten se voi kuluttaa enemmän tietokantayhteyksiä, ja tämän projektin kuormitus on hyvin pieni, miten se voi kuluttaa koko yhteyspoolin?
Puhuin tästä oudosta ongelmasta viikoittaisessa kokouksessa tänään, ja sitten yhtäkkiä ajattelin, että jokainen DbContext-instanssi täyttää tietokantayhteyden (SqlConnection), ja kun DbContextPool ei ole käytössä, heti pyynnön päätyttyä vastaava DbContext-instanssi poistetaan ja tietokantayhteys palautetaan yhteyspooliin. Kun käytetään DbContextPoolia, DbContextia ei hävitetä, vaan se siirretään takaisin DbContextPooliin pyynnön päätyttyä, ja DbContext palautetaan omaan pooliinsa, mikä tarkoittaa, että sen vastaavaa tietokantayhteyttä ei palauteta siihen yhteyspooliin, johon se kuuluu. Jokainen DbContext DbContextPoolissa vastaa yhtä tietokantayhteyttä, ja jokaiselle lisäDbContextille DbContextPoolissa on yksi vähemmän tietokantayhteys. Kun molemmat poolit ovat eri kokoisia ja DbContextPool on suurempi kuin tietokantayhteyspooli, ongelma syntyy: DbContextPool täyttää DbContextin vapaasti pooliin oman poolinsa koon mukaan (sanotaan, että se on 128), jättäen tietokantayhteyspoolin koon huomiotta (olettaen että se on 100), ja yllä oleva virhe ilmenee, kun 101. DbContext täyttyy.
Tämä projekti käyttää oletusasetuksia, aiheuttaako oletusasetus tämän ongelman?

Katsottaessa DbContextPoolin toteutuksen lähdekoodia, löytöpoolin oletuskokoraja on 128


Kun katsoo SqlConnentionin toteutuksen lähdekoodia, huomaat, että yhteyspoolien oletuskokoraja on 100

Oletusasetus laukaisee ongelman, mikä on oikeastaan pieni sudenkuoppa.

Syyn tietäen ratkaisu on yksinkertainen: aseta DbContextPoolin poolSize-arvo pienemmäksi kuin tietokanta-yhteyspoolin Max_Pool_Size





Pistetilanne

Osallistujien määrä1MB+1 myötävaikuttaa+1 Romahdus syy
Zmoli775 + 1 + 1 Astu kuoppaan ja astu siihen +1

Katso kaikki arviot





Edellinen:C# perii määrittelyn IsAssignableFrom, IsSubclassOf
Seuraava:MySQL Entity Framework Core -poikkeuskiertotie
Vastuuvapauslauseke:
Kaikki Code Farmer Networkin julkaisemat ohjelmistot, ohjelmamateriaalit tai artikkelit ovat tarkoitettu vain oppimis- ja tutkimustarkoituksiin; Yllä mainittua sisältöä ei saa käyttää kaupallisiin tai laittomiin tarkoituksiin, muuten käyttäjät joutuvat kantamaan kaikki seuraukset. Tämän sivuston tiedot ovat peräisin internetistä, eikä tekijänoikeuskiistat liity tähän sivustoon. Sinun tulee poistaa yllä oleva sisältö kokonaan tietokoneeltasi 24 tunnin kuluessa lataamisesta. Jos pidät ohjelmasta, tue aitoa ohjelmistoa, osta rekisteröityminen ja hanki parempia aitoja palveluita. Jos rikkomuksia ilmenee, ota meihin yhteyttä sähköpostitse.

Mail To:help@itsvse.com