След като преработих един метод на услуга, за да използвам многопоточност, открих, че ако повече от един потребител се опитва да поиска страница (и да извика метод на услуга) много пъти, сървърът започва да хвърля изключение „Не може да се установи връзка, пулът е изчерпан“. Нека дам пример за моя клас на обслужване.
class DocumentService {
def convertToJSON() {
docs.collect { doc ->
taskExecutor.submit({
Document.withNewSession {
def json = convertDocumentToJSON(doc)
}
} as Callable)
}.collect { it.get() }
}
def convertDocumentToJSON(doc){
def json = [:]
// ... fill json with data using doc and GORM requests
evaluateStatus(json)
return json
}
def evaluateStatus(json){
//... some work using database through GORM
}
}
Боря се с този проблем повече от седмица и не мога да намеря решение. Не разбирам добре как Grails работи със сесии, връзки и транзакции. Моето предположение е следното. Когато се извика convertDocumentToJSON, той взема връзка от пула (4 потребители, 25 нишки на потребител = 100 връзки), но след това те трябва да извикат метода evaluateStatus, който също се опитва да получи връзка от пула за собствени нужди. Но пулът е изчерпан и никоя нишка не може да освободи връзка, защото всички те чакат evaluateStatus. Така че има задънена улица. Опитах се да поставя тип разпространение на SUPPORT за evaluateStatus, но получавам изключение „обединената връзка е затворена“. Тогава си помислих, че може да работи, ако преместя извикването на evaluateStatus от convertDocumentToJSON и написах такъв код
def convertToJSON(){
docs.collect { doc ->
taskExecutor.submit({
Document.withNewSession {
def json = convertDocumentToJSON(doc)
evaluateStatus(json) // move call from convertDocumentToJSON
}
} as Callable)
}.collect { it.get() }
}
но в този случай се сблъсках със същата грешка (изчерпан басейн). Моля, дайте ми съвет какво да коригирам в кода си