2017-04-11 30 views
0


我很难编程并行服务。目标是通过异步API调用从Facebook中检索数据,然后遍历检索到的数据,同步执行GORM操作。Grails:如何在异步Web请求后将对象保存到数据库?

异步获取数据的第一步似乎很好地工作:

List<Activity> activityList = Activity.findAllByFacebookPageIsNotNullAndFetchEvents(true, [max: 100]) 
PromiseList promiseList = new PromiseList() 
activityList.each { Activity activity-> 
    promiseList << { fetchEventData(activity.facebookPage, null) } 
} 

现在我想遍历结果,如:

promiseList.onComplete { List results -> 
    results.each { ArrayList eventSet -> 
     eventSet.each { LazyMap eventData -> 
      createEvent(eventData) 
     } 
    } 
} 

createEvent()方法尝试保存新的Event

2017-04-11 10:56:47.018 ERROR --- [ctor Thread 129] o.h.engine.jdbc.spi.SqlExceptionHelper : No operations allowed after statement closed. 2017-04-11 10:56:47.024 ERROR --- [ctor Thread 124] o.h.engine.jdbc.spi.SqlExceptionHelper : No operations allowed after statement closed. 2017-04-11 10:56:47.024 ERROR --- [ctor Thread 125] o.h.engine.jdbc.spi.SqlExceptionHelper : Cannot convert value '2017-01-11 23:31:39' from column 3 to TIMESTAMP. 2017-04-11 10:56:47.025 ERROR --- [ctor Thread 105] o.h.engine.jdbc.spi.SqlExceptionHelper : No operations allowed after statement closed. 2017-04-11 10:56:47.026 ERROR --- [ctor Thread 103] o.h.engine.jdbc.spi.SqlExceptionHelper : No operations allowed after statement closed. 2017-04-11 10:56:47.026 ERROR --- [ctor Thread 107] o.h.engine.jdbc.spi.SqlExceptionHelper : No operations allowed after statement closed.

所以我想createEvent()从各个线程,而不是“主”线程调用:与此操作失败。

有人可以告诉我如何以正确的方式做到这一点?

编辑:

我也试过:

List<ArrayList> promiseResult = promiseList.get() 
promiseResult.each { ArrayList<LazyMap> eventList -> 
    eventList.each { 
     Event.findByFacebookId((String) it['id']) 
     //createEvent(it) 
    } 
} 

无法与java.lang.NullPointerException

+0

凡在你的Grails应用程序的代码被称为?使用每个新线程,您可能需要使用Event创建新的GORM事务。 withNewTransaction {//您的更新代码在这里} –

+0

这是一个交易服务。 – Fmeuer

+0

现在我使用'withNewTransaction {}'没有错误:-)但是对象不会持久保存到数据库。使用'.save(flush:true,failOnError:true)' – Fmeuer

回答

0

谢谢您的回答。我认为他们让我走上了正轨。也许我不想清楚我想达到的目标。 GORM呼叫不是异步的。尽管这仍然是一个好主意!我的方法是减慢速度:D

但是,我使用waitAll()以及之后的数据库处理来实现所需的行为。

的工作的例子是:

List<Activity> activityList = Activity.findAllByFacebookPageIsNotNullAndFetchEvents(true, [max: 100]) 
List promises = [] 
activityList.each { Activity activity-> 
    promises << task { fetchEventData(activity.facebookPage, null) } // query website asynchronously; this is really fast! 
} 

def promisesResults = waitAll(promises) 

promisesResults.each { ArrayList<LazyMap> eventList -> 
    eventList.each { LazyMap eventData -> 
     try { 
      createEvent(eventData) // DB actions; this is pretty slow 
     } catch (e) { 
      log.error(e.toString()) 
     } 
    } 
} 
1

试试这个

Event.withNewSession { 
    Event.withNewTransaction { 
     // Event update code here 
    } 
} 
相关问题