Først Lad os forstå mysql-egenskaberne.
interactive_timeout
:interaktiv timeout for mysql shell-sessioner i sekunder som mysqldump eller mysql kommandolinjeværktøjer. forbindelser er i dvaletilstand. Det meste af tiden er dette sat til en højere værdi, fordi du ikke ønsker, at det skal afbrydes, mens du laver noget på mysql cli.wait_timeout
:mængden af sekunder under inaktivitet, som MySQL vil vente, før det lukker en forbindelse på en ikke-interaktiv forbindelse på få sekunder. eksempel:forbundet fra java. forbindelser er i dvaletilstand.
Lad os nu forstå c3po-egenskaber og dets forhold til DB-rekvisitter. (Jeg kopierer lige fra dit spørgsmål)
Dette refererer til, hvor længe et forbindelsesobjekt kan være brugbart og vil være tilgængeligt i pool. Når timeout er overstået, vil c3po ødelægge det eller genbruge det.
Nu kommer problemet, når du har maxIdleTime
højere end wait_timeout
.lad os sige, hvis mxIdleTime : 50
sekunder og wait_timeout : 40 s
så er der en chance for, at du får Connection time out exception: Broken Pipe
hvis du forsøger at udføre en handling inden for de sidste 10 sekunder. Så maxIdelTime
bør altid være mindre end wait_timeout
.
I stedet for maxIdleTime kan du bruge følgende egenskaber.
idleConnectionTestPeriod
sætter en grænse for, hvor længe en forbindelse vil forblive inaktiv, før den testes. UdenpreferredTestQuery
, standarden erDatabaseMetaData.getTables()
- som er databaseagnostisk, og selvom det er et relativt dyrt opkald, er det nok fint til en relativt lille database. Hvis du er paranoid med hensyn til ydeevne, skal du bruge en forespørgsel, der er specifik for din database(i.e. preferredTestQuery="SELECT 1")
maxIdleTimeExcessConnections
vil bringe forbindelsen optælling tilbage til minPoolSize efter en stigning i aktivitet.
Bemærk venligst, at enhver af poolegenskaberne (f.eks. maxIdleTime
) påvirker kun til forbindelse, der er i pool dvs. hvis hibernate har fået en forbindelse og holder den inaktiv i mere end maxIdleTime og derefter forsøger at udføre en hvilken som helst handling, vil du få "Broken Pipe"
Det er godt at have lavere wait_timeout
på mysql, men det er ikke altid rigtigt, når du allerede har en applikation bygget. Du skal sikre dig, før du reducerer den, at du i din applikation ikke holder forbindelsen åben for mere end wait_time
ud.
Du skal også overveje, at det er en dyr opgave at skaffe en forbindelse, og hvis ventetiden er for lav, slår det hele formålet med at have forbindelsespulje, da det ofte vil forsøge at skaffe forbindelser.
Dette er især vigtigt, når du ikke udfører forbindelsesstyring manuelt, for eksempel når du bruger Spring transnational API. Foråret starter transaktionen, når du indtaster en @Transaction
annoteret metode, så den får en forbindelse fra pool. Hvis du foretager et webservicekald eller læser en fil, som vil tage mere tid end wait_time out, vil du få undtagelse.
Jeg har stået over for dette problem én gang.
I et af mine projekter havde jeg en cron, som ville lave ordrebehandling for kunder. For at gøre det hurtigere brugte jeg batchbehandling. Nu når jeg henter et parti kunder og laver noget behandling (ingen db-opkald). Når jeg forsøger at gemme alle de ordrer, jeg plejede at få knækket rør undtagelse. Problemet var, at min wait_timeout var 1 minut, og ordrebehandlingen tog længere tid end det. Så vi var nødt til at øge den til 2 minutter. Jeg kunne have reduceret batchstørrelsen, men det gjorde den samlede behandling langsommere.