Grails 3:SessionFactory Bean未在服务中注入

时间:2018-11-05 12:53:44

标签: hibernate grails gorm

我正在尝试从文件中批量添加数据,我从该门户网站读取了一种方法,以使用批处理批量添加数据

http://krixisolutions.com/bulk-insert-grails-gorm/

当我使用此技术并根据其更改我的应用程序时,我的代码无法正常工作,我已经工作了好几天了,以寻找方法来批量保存数据,从而使过程更快,通过简单的手动刷新需要4分钟要在数据库中保存1000行数据,我想使这段时间尽可能短

在下面给出的代码中,每当我调试在SessionFactory之后停止运行的代码时,我都不明白问题出在哪里,因为我是新手,对SessionFactory或事务没有任何经验。

这是我的代码:

   runAsync {
            res = benchmark { result ->
                    Session session = SessionFactory.openSession()
Transaction tx = (Transaction)session.beginTransaction()




                    groovyFile.eachLine {


                        String[] tagData = it.split(',')

                        def isTimeToLive = true


                        if (isTimeToLive) {
                            try {
                                caller = new Caller(callingNumber: 
                       tagData.getAt(0), callerName: tagData.getAt(1))
                                session.save(caller)
                            } catch (Exception ex) {
                                log.error(ex.getMessage())
                            }

                            caller.validate()
                            if (caller.hasErrors()) {
                                println("message", "Invalid calling number. Digits can only be from 10 to 15.")
                            }

                            callCallerList = new CallCallerList(caller: caller, callerList: callerList)
                            callCallerList.validate()
                            if (callCallerList.hasErrors()) {
                                println("message", "Invalid calling number. Digits can only be from 10 to 15.")
                            } else {
                                session.save(callCallerList)
                            }

                        }
                        count++;
                        if (count % 100 == 0) {
                            session?.flush()
                            session?.clear()
                        }
                    }
                    tx.commit();
                    session.close();

                }


            }

        }

2 个答案:

答案 0 :(得分:1)

在Grails中,您可以简单地使用withSession{}withTransaction{}

我会这样写:

Caller.withTransaction{
  int count = 0
  groovyFile.splitEachLine( ',' ){ String[] line ->
    Caller caller = new Caller( callingNumber:line[ 0 ], callerName:line[ 1 ] )
    if( !caller.save( flush:0 == count % 100 ) ) println caller.errors
    count++
  }
}

您不应真正手动处理会话。

更新

  

为什么事务在会话失败时快速插入?

不。通常,事务会自动包装会话,因此withSession{}的运行速度与withTransaction{}一样快。

  

是因为会话未正确清理高速缓存,还是因为每个sql查询正在执行其自身的刷新操作?

是的,除非您flushclose对其进行清理,否则不会清除会话的缓存。这是在我的代码或有关GORM或Hibernate中的批量处理的任何建议中完成的。

答案 1 :(得分:0)

openSession不是静态方法,如果还没有会话,则应该注入sessionFactory并打开一个会话。

class SomeService {
  def sessionFactory
  void someMethod() {
    def session = sessionFactory.openSession() //or sessionFactory.currentSession, not sure how this works with async operations
    //all your stuff
    if(<threshold>) { 
       session.flush()
       session.clear() //helps performance on exceptionally large imports, probably not so much on ~1000 records
    }
  }
}