Grails:如何在异步网络请求后将对象保存到数据库?
Grails: How to save objects to DB after async web requests?
我很难对并行服务进行编程。目标是使用异步 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 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()
是从各种线程而不是 "main" 线程调用的。
有人可以告诉我如何以正确的方式做到这一点吗?
编辑:
我也试过:
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())
}
}
}
我很难对并行服务进行编程。目标是使用异步 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 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()
是从各种线程而不是 "main" 线程调用的。
有人可以告诉我如何以正确的方式做到这一点吗?
编辑:
我也试过:
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())
}
}
}