我有一个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条记录或更多时,我得到了这样的堆栈跟踪。这看起来很奇怪,因为我的调试显示解码过程工作正常,并返回正确的解码记录值。当我在同一个线程中调用整个过程时,每个事情似乎都是正确的。 有谁知道出了什么问题?我将不胜感激任何建议。也许我应该使用其他解决方案。哪个?
答案 0 :(得分:0)
我找到了解决方案:当我为promise对象处理onError和onComplete时,一切正常。似乎这些处理程序在线程完成之前执行,这就是为什么对于较大的文件我得到了异常。我正在考虑,如果它是Promise概念中的错误,或者我错误地理解它。