简体   繁体   English

Grails的。 无法建立连接,池已耗尽

[英]Grails. Cannot get a connection, pool exhausted

After reworking one service method in order to use multithreading I found out that if more than one user is trying to request page (and call service method) many times, the server begins throwing "Cannot get a connection, pool exhausted" exception. 在重新设计一种服务方法以使用多线程之后,我发现如果有多个用户尝试多次请求页面(并调用服务方法),则服务器将引发“无法获取连接,池已耗尽”异常。 Let me provide an example of my service class. 让我提供一个服务类示例。

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

I've been struggling with this issue for more than week and I can't find a solution. 我已经为这个问题苦苦挣扎了一个多星期,但找不到解决方案。 I don't understand well how Grails works with sessions, connections and transactions. 我不太了解Grails如何处理会话,连接和事务。 My guess is following. 我的猜测如下。 When convertDocumentToJSON is called, it takes connection from pool (4 users, 25 threads per user = 100 connections) but then they need to call evaluateStatus method, which also tries to obtain connection from pool for its own needs. 调用convertDocumentToJSON时,它将从池中获取连接(4个用户,每个用户25个线程= 100个连接),但随后他们需要调用validateStatus方法,该方法还尝试从池中获取其自身需要的连接。 But pool is exhausted, and no one thread can release connection because all of them are waiting for evaluateStatus. 但是池已耗尽,并且没有一个线程可以释放连接,因为所有线程都在等待评估状态。 So, there is deadlock. 因此,存在僵局。 I tried to place SUPPORT propagation type for evaluateStatus, but I get "pooled connection has been closed" exception. 我尝试将SUPPORT传播类型放置为validateStatus,但出现“池连接已关闭”异常。 Then I thought it might work if I move evaluateStatus call from convertDocumentToJSON and wrote such code 然后我认为如果我将convertDocumentToJSON中的valuateStatus调用移动并编写了这样的代码,那可能会起作用

def convertToJSON(){
  docs.collect { doc ->
    taskExecutor.submit({
        Document.withNewSession {
            def json = convertDocumentToJSON(doc)
            evaluateStatus(json) // move call from convertDocumentToJSON
        }
      } as Callable)
  }.collect { it.get() }
}

but in this case I also faced the same error (exhausted pool). 但是在这种情况下,我也遇到了相同的错误(资源耗尽)。 Please, give me advice what should I fix in my code 请给我建议,我应该在代码中修复什么

You need something to throttle the use of connections, try using GPars eg 您需要限制连接的使用,例如尝试使用GPars

import groovyx.gpars.GParsPool

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

There are XXXXParallel versions of the usual groovy collection methods eg collectParallel which you can play around with to assist with performance. 常规groovy收集方法有XXXXParallel版本,例如collectParallel,您可以使用它来提高性能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM