【发布时间】:2016-12-29 19:48:00
【问题描述】:
我有一个 Grails 应用程序(2.4.3 版),但在单独的线程中调用服务方法时遇到问题。我根据文档使用 Promise 概念。我有两个服务:第一个我有保存父实体的 main 方法,然后第二个保存给定父实体的子记录。我想在单独的线程中实现保存子记录。主要服务如下:
@Transactional
class ParentService {
AsyncSourceService asyncSourceService
Parent save(Date dateFrom, Date dateTill, File sourceFile){
log.info "save - start"
Parent parent = new Parent(dateFrom: dateFrom, dateTill: dateTill, status: Status.LOAD_IN_PROGRESS)
parent.save(flush:true)
//TODO: asynchronous call
//sourceRecordService.decodeRecords(parent, sourceFile)
def promise = asyncSourceService.decodeSourceFile(Parent, sourceFile)
promise.onComplete { results ->
println("#### Results: $results ####")
}
promise.onError { Throwable t ->
//t.printStackTrace()
println "####### ${t.message}"
}
return parent
}
}
SourceService 看起来像:
@Transactional
class SourceService {
Integer decodeSourceFile(Parent parent, File sourceFile){
int lineNo = 0
sourceFile.eachLine {line->
// convert line to record
sourceRecord.save()
lineNo++
}
return new IntegerlineNo
}
}
异步调用服务的包装器如下所示:
class AsyncSourceervice {
@DelegateAsync
SourceService sourceService
Promise<Integer> decodeSourceFile(Parent parent, File sourceFile){
Promises.task {
sourceService.decodeSourceFile(parent, sourceFile)
}
}
}
而且它不起作用。当我运行一个进程时,我得到:
| Error 2014-10-14 08:47:26,586 [Actor Thread 2] ERROR gpars.LoggingPoolFactory - Async execution error: null
Message: null
Line | Method
->> 72 | doCall in org.grails.async.factory.gpars.GparsPromise$_onError_closure2
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 62 | run in groovyx.gpars.dataflow.DataCallback$1
| 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 744 | run . . . in java.lang.Thread
我知道解码的服务方法有效,它解码了正确的记录数,但没有发生回调方法(onError 或 onComplete 都没有)。怎么了? 我注意到对于记录很少(少于 50 条)的文件,它可以正常工作,但是当文件包含大约 100 条或更多记录时,我会得到这样的堆栈跟踪。这似乎很奇怪,因为我的调试显示解码过程工作正常,它返回解码记录的正确值。当我在同一个线程中调用整个过程时,一切似乎都是正确的。 有谁知道出了什么问题?我将不胜感激任何建议。也许我应该使用其他解决方案。哪个?
【问题讨论】:
-
愚蠢、反动、错误的标题。 Grails 并发性并没有从根本上被破坏。如果是这样,就会出现一些提示 - 测试失败,有人使用快照构建进行开发和/或测试,等等。
-
好吧,你说得对,我改了标题。谢谢
标签: multithreading grails concurrency