Grails:如何在异步 Web 请求后将对象保存到数据库?




我很难编写并行服务。目标是使用异步API调用从Facebook检索数据,然后迭代检索到的数据,同步执行GORM操作。

异步获取数据的第一步似乎适用于:

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 错误 --- [ctor 线程 129] o.h.engine.jdbc.spi.SqlExceptionHelper :语句关闭后不允许任何操作。 2017-04-11 10:56:47.024 错误 --- [ctor 线程 124] o.h.engine.jdbc.spi.SqlExceptionHelper :语句关闭后不允许任何操作。 2017-04-11 10:56:47.024 错误--- [ctor 线程 125] o.h.engine.jdbc.spi.SqlExceptionHelper:无法将值"2017-01-11 23:31:39"从第 3 列转换为时间戳。 2017-04-11 10:56:47.025 错误 --- [ctor 线程 105] o.h.engine.jdbc.spi.SqlExceptionHelper :语句关闭后不允许任何操作。 2017-04-11 10:56:47.026 错误 --- [ctor 线程 103] o.h.engine.jdbc.spi.SqlExceptionHelper :语句关闭后不允许任何操作。 2017-04-11 10:56:47.026 错误--- [ctor 线程 107] o.h.engine.jdbc.spi.SqlExceptionHelper :语句关闭后不允许任何操作。

所以我想createEvent()是从各种线程而不是"主"线程调用的。

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

编辑:

我也试过:

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

失败并显示java.lang.NullPointerException

试试这个

Event.withNewSession {
Event.withNewTransaction {
// Event update code here
}
}

感谢您的回答。我认为他们让我走上了正确的轨道。也许我不清楚我想要实现的目标。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())
}
}
}

相关内容

  • 没有找到相关文章

最新更新