2013-02-11 46 views
4

我最近爲我的Grails 1.3.7項目添加了一個新功能,在某些Domain對象被保存到數據庫之後,我想要做一些後處理。我在這些Domain對象中使用了afterInsert()方法。Grails ::超時等待空閒對象:: GORM事件方法

這個後期處理由對數據庫的附加查找組成,以確定是否需要採取其他操作,例如對其他API執行RESTful調用。自從添加這個新代碼以來,我一直無法部署到我們的生產環境中。在5分鐘內,我開始看到下面的堆棧跟蹤一遍又一遍地重複。我無法在我的開發環境中重現這一點。

2013-02-10 03:39:45,384 [http-bio-8443-exec-126] ERROR org.hibernate.util.JDBCExceptionReporter - Cannot get a connection, pool error Timeout waiting for idle object 
2013-02-10 03:39:45,401 [http-bio-8443-exec-126] ERROR org.codehaus.groovy.grails.web.errors.GrailsExceptionResolver - Exception occurred when processing request: [POST] /events 
Stacktrace follows: 
2013-02-10 03:39:45,406 [http-bio-8443-exec-126] ERROR ErrorController - Timeout waiting for idle object 
org.codehaus.groovy.grails.web.errors.GrailsWrappedRuntimeException: Timeout waiting for idle object 
    at org.codehaus.groovy.grails.web.errors.GrailsExceptionResolver.resolveException(GrailsExceptionResolver.java:79) 
    at org.springframework.web.servlet.DispatcherServlet.processHandlerException(DispatcherServlet.java:987) 
    at org.codehaus.groovy.grails.web.servlet.GrailsDispatcherServlet.doDispatch(GrailsDispatcherServlet.java:319) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644) 
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:641) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:70) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:70) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:70) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:749) 
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:487) 
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:412) 
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:339) 
    at org.codehaus.groovy.grails.web.util.WebUtils.forwardRequestForUrlMappingInfo(WebUtils.java:298) 
    at org.codehaus.groovy.grails.web.util.WebUtils.forwardRequestForUrlMappingInfo(WebUtils.java:264) 
    at org.codehaus.groovy.grails.web.util.WebUtils.forwardRequestForUrlMappingInfo(WebUtils.java:255) 
    at org.codehaus.groovy.grails.web.mapping.filter.UrlMappingsFilter.doFilterInternal(UrlMappingsFilter.java:183) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.codehaus.groovy.grails.web.sitemesh.GrailsPageFilter.obtainContent(GrailsPageFilter.java:245) 
    at org.codehaus.groovy.grails.web.sitemesh.GrailsPageFilter.doFilter(GrailsPageFilter.java:134) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:369) 
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109) 
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:112) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187) 
    at org.codehaus.groovy.grails.plugins.springsecurity.RequestHolderAuthenticationFilter.doFilter(RequestHolderAuthenticationFilter.java:40) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    at org.codehaus.groovy.grails.plugins.springsecurity.MutableLogoutFilter.doFilter(MutableLogoutFilter.java:79) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:168) 
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237) 
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:69) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.codehaus.groovy.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:65) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) 
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237) 
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) 
Caused by: java.util.NoSuchElementException: Timeout waiting for idle object 

我目前被困在Grails的1.3.7,因爲我們使用的是Grails Multi-Tenant Plugin (Core)不使用Grails 2.0工作,我們一直無法遷移從該插件了。

在域對象methods such as afterInsert內有什麼可以做什麼的已知問題嗎?我已經使用該代碼嘗試了幾種不同的方法。最初,我使用Executor Plugin來產生一個新的線程。我認爲這可能是我的問題,所以我刪除了引入了一些Hibernate會話沖洗問題的內容,因此我用DomainObject.withNewSession {}來包裝每個調用,這使得代碼再次在我的開發環境中工作,但生產失敗。

我還添加了一個檢查外部配置,看看是否允許關閉這個新功能......當我這樣做時,問題就消失了。

+0

看來你的另一API調用花費很長的時間來完成,這是拋出超時異常。對這個API的調用決定了這個過程是否以成功結束?也許你可以改變這個在服務中做,或者做到異步,不要鎖定交易。 – 2013-02-11 18:27:50

+0

@SérgioMichels好的建議。我們今天早上也想到了這一點,但還沒有能夠測試這個理論。現在我再給它一次,看看我是否可以在本地複製,以避免再次在生產環境中進行測試。對其他API *的調用應該很快。它只是接收到調用並立即返回,然後在另一個線程中進行處理。唯一的時間應該是往返。 – ShatyUT 2013-02-11 18:30:37

回答

1

我們能夠通過Tomcat上數據源上的新配置來解決此問題。我們正在運行Tomcat 7.0.32,它現在提供了一個新的連接池工廠。切換到更正我們的問題。

得愛一個不在代碼中的修復!

閱讀關於這裏的新連接池:

http://people.apache.org/~fhanik/jdbc-pool/jdbc-pool.html