在修改了一种服务方法以使用多线程后,我发现如果多个用户尝试多次请求页面(并调用服务方法),服务器开始抛出“无法获得连接,池耗尽”异常。让我提供一个我的服务类的例子。
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 方法,该方法也尝试从池中获取连接以满足自己的需要。但是pool已经用完了,没有一个线程可以释放连接,因为它们都在等待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() }
}
但在这种情况下,我也遇到了同样的错误(池耗尽)。请给我建议我应该在我的代码中修复什么