在重新编写一个服务方法以便使用多线程后,我发现如果多个用户尝试多次请求页面(和调用服务方法),服务器就会开始抛出"无法获得连接,池用尽"例外。让我举一个我的服务类的例子。
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。所以,有僵局。我尝试为evaluateStatus放置SUPPORT传播类型,但我得到了#34;池连接已经关闭了#34;例外。然后我认为如果我从convertDocumentToJSON移动evaluateStatus调用并编写这样的代码可能会有用
def convertToJSON(){
docs.collect { doc ->
taskExecutor.submit({
Document.withNewSession {
def json = convertDocumentToJSON(doc)
evaluateStatus(json) // move call from convertDocumentToJSON
}
} as Callable)
}.collect { it.get() }
}
但在这种情况下我也遇到了同样的错误(耗尽的游泳池)。请告诉我应该在我的代码中修复什么
答案 0 :(得分:0)
您需要一些东西来限制连接的使用,尝试使用GPars例如
import groovyx.gpars.GParsPool
GParsPool.withPool() {
docs.collect {
// do your stuff...
}
}
通常的groovy收集方法有XXXXParallel版本,例如collectParallel,你可以玩,以协助表现。