Първо нека разберем свойствата на mysql.
interactive_timeout:интерактивно време за изчакване за сесии на mysql обвивка за секунди като mysqldump или mysql инструменти за команден ред. връзките са в състояние на заспиване. През повечето време това е настроено на по-висока стойност, защото не искате връзката да бъде прекъсната, докато правите нещо на mysql cli.wait_timeout:количеството секунди по време на неактивност, което MySQL ще изчака, преди да затвори връзка при неинтерактивна връзка за секунди. пример:свързан от java. връзките са в състояние на заспиване.
Сега нека разберем свойствата на c3po и връзката им с DB реквизитите. (Просто ще копирам от вашия въпрос)
Това се отнася до това колко дълго обектът на връзка може да бъде използван и ще бъде наличен в пула. След като времето за изчакване изтече, c3po ще го унищожи или ще го рециклира.
Сега проблемът идва, когато имате maxIdleTime по-високо от wait_timeout .да речем, ако mxIdleTime : 50 секунди и wait_timeout : 40 s тогава има шанс да получите Connection time out exception: Broken Pipe ако се опитате да извършите някаква операция през последните 10 секунди. Така че maxIdelTime винаги трябва да е по-малко от wait_timeout .
Вместо maxIdleTime можете да имате следните свойства.
idleConnectionTestPeriodзадава ограничение за това колко дълго връзката ще остане неактивна, преди да я тества. БезpreferredTestQuery, по подразбиране еDatabaseMetaData.getTables()- което не зависи от базата данни и въпреки че е сравнително скъпо обаждане, вероятно е добре за сравнително малка база данни. Ако сте параноични относно производителността, използвайте специфичен за вашата база данни aquery(i.e. preferredTestQuery="SELECT 1")maxIdleTimeExcessConnectionsще върне обратното възстановяване на connectionCount до minPoolSize след скок в активността.
Моля, имайте предвид, че някое от свойствата на пула (напр. maxIdleTime ) засяга само връзките, които са в пул т.е. ако hibernate е придобил връзка и я държи неактивна повече от maxIdleTime и след това се опита да извърши каквато и да е операция, тогава ще получите „Счупена тръба“
Добре е да имате по-нисък wait_timeout на mysql, но не винаги е правилно, когато вече имате изградено приложение. Трябва да се уверите, преди да го намалите, че във вашето приложение не поддържате връзката отворена за повече от wait_time вън.
Също така трябва да имате предвид, че придобиването на връзка е скъпа задача и ако времето за изчакване е твърде малко, тогава това надминава цялата цел на наличието на пул за връзки, тъй като често ще се опитва да придобие връзки.
Това е особено важно, когато не извършвате управление на връзката ръчно, например когато използвате Spring transnational API. Spring стартира транзакция, когато въведете @Transaction анотиран метод, така че да придобие връзка от пула. Ако извършвате извикване на уеб услуга или четете някакъв файл, което ще отнеме повече време от wait_time out, тогава ще получите изключение.
Сблъсквал съм се с този проблем веднъж.
В един от моите проекти имах cron, който обработваше поръчки за клиенти. За да го направя по-бързо използвах пакетна обработка. Сега, след като извличам партида от клиенти и извършвам някаква обработка (без db повиквания). Когато се опитах да запазя всички поръчки, използвах изключение за счупена тръба. Проблемът беше, че моят wait_timeout беше 1 минута и обработката на поръчката отнемаше повече време от това. Така че трябваше да го увеличим до 2 минути. Можех да намаля размера на партидата, но това правеше цялостната обработка по-бавна.