【问题标题】:PooledConnection Issue with MultiTenancy in GrailsGrails 中多租户的 PooledConnection 问题
【发布时间】:2021-12-16 20:38:56
【问题描述】:

当我第二次尝试访问服务中的多租户域“成员”时,我遇到了“池连接已关闭”问题。我正在使用带有 MySQL 数据库的 Grails 3.3.11。我无法弄清楚我做错了什么。

我有一个控制器定义如下 -

@CurrentTenant
class GroupController{
 def save(){
   groupService.getMember()
   groupService.updateMember()
 }
}

我的服务定义如下 -

@Transactional
class GroupService{
 def getMember(){
   return Member.createCriteria().list{
     eq('customer','test')
   }
 }

 def updateMember(){
   Member.executeUpdate("Update member set group='testGroup'")
 }
}

当我点击 updatemember() 函数时,我收到以下错误 -

PooledConnection has already been closed.. Stacktrace follows:
java.lang.reflect.InvocationTargetException
    at org.grails.core.DefaultGrailsControllerClass$ReflectionInvoker.invoke(DefaultGrailsControllerClass.java:211)
    at org.grails.core.DefaultGrailsControllerClass.invoke(DefaultGrailsControllerClass.java:188)
    at org.grails.web.mapping.mvc.UrlMappingsInfoHandlerAdapter.handle(UrlMappingsInfoHandlerAdapter.groovy:90)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:54)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114)
    at grails.plugin.springsecurity.web.UpdateRequestContextHolderExceptionTranslationFilter.doFilter(UpdateRequestContextHolderExceptionTranslationFilter.groovy:64)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at grails.plugin.springsecurity.web.filter.GrailsHttpPutFormContentFilter.doFilterInternal(GrailsHttpPutFormContentFilter.groovy:54)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter.doFilter(GrailsAnonymousAuthenticationFilter.groovy:54)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:158)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.deerwalk.impl.CustomCasAuthenticationFilter.doFilter(CustomCasAuthenticationFilter.java:119)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.groovy:64)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at grails.plugin.springsecurity.web.SecurityRequestHolderFilter.doFilter(SecurityRequestHolderFilter.groovy:58)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
    at org.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:77)
    at org.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:67)
    at org.jasig.cas.client.session.SingleSignOutFilter.doFilter(SingleSignOutFilter.java:97)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

我正在使用多个数据源,它们的定义如下 -

dataSource:
  pooled: true
  driverClassName: com.mysql.cj.jdbc.Driver
  #dbCreate: "update"
  url: jdbc:mysql://localhost:3306/index?zeroDateTimeBehavior=convertToNull&autoReconnect=true&relaxAutoCommit=true&useSSL=false
  username: root
  password: root
  properties:
    initialSize: 5
    maxActive: 100
    minIdle: 5
    maxIdle: 25
    maxWait: 10000
    maxAge: 10 * 60000
    timeBetweenEvictionRunsMillis: 1800000
    minEvictableIdleTimeMillis: 1800000
    validationQuery: "SELECT 1"
    validationInterval: 15000
    testWhileIdle: true
    testOnBorrow: true
    testOnReturn: false
    jdbcInterceptors: ConnectionState
    defaultTransactionIsolation: java.sql.Connection.TRANSACTION_READ_COMMITTED
dataSources:
 
  shard1:
    url: jdbc:mysql://localhost:3306/shard1?zeroDateTimeBehavior=convertToNull&autoReconnect=true&relaxAutoCommit=true&useSSL=false
    dbCreate: none

  shard2:
    url: jdbc:mysql://localhost:3306/shard2?zeroDateTimeBehavior=convertToNull&autoReconnect=true&relaxAutoCommit=true&useSSL=false
    dbCreate: none

【问题讨论】:

    标签: java spring hibernate grails groovy


    【解决方案1】:

    尝试在控制器和服务之间引入一个额外的层。 创建一个由控制器调用的新类,并在新类中添加引入 currentTenant 注释,我过去以类似的方式解决了这个问题,但我不知道为什么解决了这个问题。

    例如:-

    class GroupController{
        def save(){
          new GroupHandler().handleSave();
        }
      }
        
    @CurrentTenant
    class GroupHandler{
        
      def groupService // initialize service bean here 
      def handleSave(){
           groupService.getMember()
           groupService.updateMember()
        }
        
    }
    

    【讨论】:

      猜你喜欢
      • 2021-10-31
      • 2021-07-04
      • 2015-08-07
      • 2016-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-10
      • 1970-01-01
      相关资源
      最近更新 更多