Šis straipsnis yra veidrodinis mašininio vertimo straipsnis, spauskite čia norėdami pereiti prie originalaus straipsnio.

Rodinys: 24272|Atsakyti: 0

[Šaltinis] EF Core duobė: DbContextPool sukelia duomenų bazės ryšio telkinio ryšio išeikvojimą

[Kopijuoti nuorodą]
Publikuota: 2019-11-18 14:41:59 | | |
DbContextPool yra nauja funkcija, pristatyta ASP.NET Core 2.1, kuri taupo pridėtines išlaidas kuriant DbContext egzempliorių, tačiau joje yra paslėpta nedidelė duobė.
Neseniai "ASP.NET Core" projektas kurį laiką buvo vykdomas nepertraukiamai, o tada žurnaluose pasirodė klaida, kad duomenų bazės ryšių telkinys pasiekė maksimalų ryšių skaičių:


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.
   adresu System.Data.Common.ADP.ExceptionWithStackTrace(Išimtis e)
Iš pradžių maniau, kad tai buvo kažkoks kodas, dėl kurio DbContext tinkamai disponavo, bet kode neradau jokių užuominų. Vėliau tikrai nebuvo ko abejoti, tik DbContextPool, todėl bandžiau pašalinti DbContextPool, bet klaida išnyko. Tai iš tiesų sukėlė DbContextPool, tačiau žmonės stebisi, kad DbContextPool iš pradžių buvo skirtas sutaupyti DbContext egzempliorių kūrimo pridėtines išlaidas, taigi kaip jis gali sunaudoti daugiau duomenų bazių ryšių, o šio projekto apkrova yra labai maža, kaip jis gali sunaudoti visą ryšio telkinį?
Aš kalbėjau apie šią keistą problemą savaitės susitikime šiandien, ir tada aš staiga maniau, kad kiekvienas DbContext egzempliorius užims duomenų bazės ryšį (SqlConnection), ir kai DbContextPool nėra įjungtas, kai tik užklausa baigiasi, atitinkamas DbContext egzempliorius bus pašalintas, ir duomenų bazės ryšys bus įdėtas atgal į ryšio baseiną. Naudojant DbContextPool, DbContext nebus pašalintas, bet bus grąžintas į DbContextPool pasibaigus užklausai, o DbContext bus grąžintas atgal į savo telkinį, o tai reiškia, kad atitinkamas duomenų bazės ryšys nebus grąžintas į ryšių telkinį, kuriam jis priklauso. Kiekvienas DbContextPool DbContext atitinka duomenų bazės ryšį, o kiekvienam papildomam DbContext DbContextPool duomenų bazės ryšių telkinyje bus vienu duomenų bazės ryšiu mažiau. Kai du telkiniai yra skirtingo dydžio, o DbContextPool yra didesnis nei duomenų bazės ryšio telkinys, iškyla problema, DbContextPool laisvai užpildo DbContext į telkinį pagal savo telkinio dydį (tarkime, kad jis yra 128), nepaisydamas duomenų bazės ryšio telkinio dydžio (darant prielaidą, kad jis yra 100), o aukščiau pateikta klaida įvyks, kai bus užpildytas 101-asis DbContext.
Šis projektas naudoja numatytuosius parametrus, ar numatytasis nustatymas sukelia šią problemą?

Žvelgiant į DbContextPool diegimo šaltinio kodą, numatytasis aptikimo telkinio dydžio apribojimas yra 128


Pažvelgę į "SqlConnention" diegimo šaltinio kodą, pamatysite, kad numatytasis ryšių telkinių dydžio apribojimas yra 100

Numatytasis nustatymas sukels problemą, o tai tikrai yra nedidelė spąstai.

Žinant priežastį, sprendimas yra paprastas, nustatykite DbContextPool poolSize į mažesnį nei duomenų bazės ryšio telkinio Max_Pool_Size





Vertinimas pagal

Dalyvių skaičius1MB+1 Prisidėti prie+1 Žlugimo priežastis
Zmoli775 + 1 + 1 Žingsnis ant duobės ir žingsnis ant jos +1

Peržiūrėti visus įvertinimus





Ankstesnis:C# paveldi IsAssignableFrom, IsSubclassOf nustatymą
Kitą:"MySQL" objektų sistemos pagrindinis išimties sprendimas
Atsakomybės apribojimas:
Visa programinė įranga, programavimo medžiaga ar straipsniai, kuriuos skelbia Code Farmer Network, yra skirti tik mokymosi ir mokslinių tyrimų tikslams; Aukščiau nurodytas turinys negali būti naudojamas komerciniais ar neteisėtais tikslais, priešingu atveju vartotojai prisiima visas pasekmes. Šioje svetainėje pateikiama informacija gaunama iš interneto, o ginčai dėl autorių teisių neturi nieko bendra su šia svetaine. Turite visiškai ištrinti aukščiau pateiktą turinį iš savo kompiuterio per 24 valandas nuo atsisiuntimo. Jei jums patinka programa, palaikykite autentišką programinę įrangą, įsigykite registraciją ir gaukite geresnes autentiškas paslaugas. Jei yra kokių nors pažeidimų, susisiekite su mumis el. paštu.

Mail To:help@itsvse.com