performance - Grails hibernate session 批量

标签 performance hibernate grails grails-orm

只要没有超过 10.000 个对象的批次,GORM 开箱即用。如果没有优化,您将面临 outOfMemory 问题。

常见的解决方案是刷新()和清除() session 每个 n(例如n = 500)个对象:

Session session = sessionFactory.currentSession
Transaction tx = session.beginTransaction();
def propertyInstanceMap = org.codehaus.groovy.grails.plugins.DomainClassGrailsPlugin.PROPERTY_INSTANCE_MAP

Date yesterday = new Date() - 1

Criteria c = session.createCriteria(Foo.class)
c.add(Restrictions.lt('lastUpdated',yesterday))
ScrollableResults rawObjects = c.scroll(ScrollMode.FORWARD_ONLY)

int count=0;
while ( rawObjects.next() ) {
    def rawOject = rawObjects.get(0);

    fooService.doSomething()

    int batchSize = 500
    if ( ++count % batchSize == 0 ) {
        //flush a batch of updates and release memory:
        try{
            session.flush();
        }catch(Exception e){
            log.error(session)
            log.error(" error: " + e.message)
            throw e
        }
        session.clear();
        propertyInstanceMap.get().clear()
    }
}

session.flush()
session.clear()
tx.commit()

但是有一些问题我无法解决:
  • 如果我使用 currentSession,那么 Controller 会因为 session 为空而失败
  • 如果我使用 sessionFactory.openSession(),那么在 FooService 中仍然使用 currentSession。因为我可以使用 session.save(object) 符号。但这意味着,我必须修改 fooService.doSomething() 并为单个操作(常见的 grails 符号,如 fooObject.save() )和批处理操作(session.save(fooObject() .. 符号)修改代码。
  • 如果我使用 Foo.withSession{session->} 或 Foo.withNewSession{session->},那么 Foo 类的对象会按预期被 session.clear() 清除。所有其他对象都没有被清除(),导致内存泄漏。
  • 因为我可以使用 evict(object) 手动清除 session 。但是由于关联的自动获取,几乎不可能获得所有相关对象。

  • 所以我不知道如何在不使 FooService.doSomething() 更复杂的情况下解决我的问题。我正在为所有域寻找类似 withSession{} 的东西。或者在开始时保存 session (Session tmp = currentSession)并执行类似 sessionFactory.setCurrentSession(tmp) 的操作。两者都不存在!

    任何想法都欢迎!

    最佳答案

    我建议使用无状态 session 进行这种批处理。看到这个帖子:Using StatelessSession for Batch processing

    关于performance - Grails hibernate session 批量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13748764/

    相关文章:

    performance - 正确处理 ISO-Prolog 中的非正规 float

    java - 方法抛出 'org.hibernate.LazyInitializationException' 异常

    java - 如何在 Hibernate 上使用 QueryDSL 过滤映射值?

    java - Hibernate+PostgreSQL 抛出JDBCConnectionException : Cannot open connection

    grails - Grails jasper pdf net.sf.jasperreports.engine.JRException:图片读取失败

    grails - 命名查询日期(月和年)

    json - Ajax成功,但JSON中的Grails为空

    c++ - 为什么 AVX 点积比原生 C++ 代码慢

    scala - 为什么在 Scala 中压缩比 zip 快?

    javascript - 如何通过 AJAX 发送数千个对象?