Grails的。无法获得连接,池耗尽

时间:2017-05-29 13:25:50

标签: multithreading grails connection-pooling jdbc-pool

在重新编写一个服务方法以便使用多线程后,我发现如果多个用户尝试多次请求页面(和调用服务方法),服务器就会开始抛出"无法获得连接,池用尽"例外。让我举一个我的服务类的例子。

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() }
}

但在这种情况下我也遇到了同样的错误(耗尽的游泳池)。请告诉我应该在我的代码中修复什么

1 个答案:

答案 0 :(得分:0)

您需要一些东西来限制连接的使用,尝试使用GPars例如

import groovyx.gpars.GParsPool

GParsPool.withPool() {
    docs.collect {
        // do your stuff...
    }
}

通常的groovy收集方法有XXXXParallel版本,例如collectParallel,你可以玩,以协助表现。