Grails groovy太多的休眠连接

时间:2014-09-11 15:51:21

标签: java hibernate batch-file grails groovy

我正在努力进行手动交易管理。背景:我需要运行运行批处理的quarz crons。建议批处理手动决定何时刷新数据库,以免将应用程序减慢到很多。

我有一个池化的hibernate连接,如下所示

dataSource {
        pooled = true
        driverClassName = "com.mysql.jdbc.Driver"
        dialect = "org.hibernate.dialect.MySQL5InnoDBDialect"
        properties {
            maxActive = 50
            maxIdle = 25
            minIdle = 1
            initialSize = 1
            minEvictableIdleTimeMillis = 60000
            timeBetweenEvictionRunsMillis = 60000
            numTestsPerEvictionRun = 3
            maxWait = 10000
            testOnBorrow = true
            testWhileIdle = true
            testOnReturn = false
            validationQuery = "SELECT 1"
            validationQueryTimeout = 3
            validationInterval = 15000
            jmxEnabled = true
            maxAge = 10 * 60000
            // http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html#JDBC_interceptors
            jdbcInterceptors = "ConnectionState;StatementCache(max=200)"
        }
    }

    hibernate {
        cache.use_second_level_cache = false
        cache.use_query_cache = false
        cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory'
        show_sql = false
        logSql = false
    }

cron作业在我运行的服务中调用服务执行以下操作:

    for(int g=0; g<checkResults.size() ;g++) {
        def tmpSearchTerm = SearchTerm.findById((int)results[g+i][0])
        tmpSearchTerm.count=((String)checkResults[g]).toInteger()
        batch.add(tmpSearchTerm)
    }


        //increase counter
        i+=requestSizeTMP
        if (i%(requestSize*4)==0 || i+1==results.size()){
            println "PREPARATION TO WRITE:" + i
            SearchTerm.withSession{
                def tx = session.beginTransaction()
                for (SearchTerm s: batch) {
                    s.save()
                }
                batch.clear()
                tx.commit()
                println ">>>>>>>>>>>>>>>>>>>>>writing: ${i}<<<<<<<<<<<<<<<<<<<<<<"
            }
            session.flush()
            session.clear()
        }
    }

所以我在批处理中添加东西,直到我有足够的(4倍的请求大小或最后一项),然后我尝试将其写入数据库。

一切正常......但不知何故,代码似乎打开了hibernate事务并且没有关闭它们。我真的不明白为什么,但我得到一个硬错误,tomcat崩溃与太多的连接。我有2个问题,我不明白:

1)如果数据源是池并且maxActive是50,如果tomcat的限制是500,我怎么能得到太多的连接错误。

2)如何明确终止交易,以便我没有这么多开放的连接?

1 个答案:

答案 0 :(得分:0)

您可以使用withTransaction,因为它会管理交易。

例如

Account.withTransaction { status ->
    def source = Account.get(params.from)
    def dest = Account.get(params.to)

    int amount = params.amount.toInteger()
    if (source.active) {
        source.balance -= amount

        if (dest.active) {
            dest.amount += amount
        }
        else {
            status.setRollbackOnly()
        }
    }
}

您可以在http://grails.org/doc/latest/ref/Domain%20Classes/withTransaction.html

中查看交易

您可以在https://stackoverflow.com/a/19692615/1610918

中看到withSession和withTransaction之间的区别

------ UPDATE -----------

但我更希望你使用服务,它可以从工作中调用。