I am trying to create a specific type of background processing setup in a grails application.
- A fixed thread pool size exists only during the job package
- A single session is supported by each thread.
- Each task is performed in a separate transaction.
I am trying to start the work as follows:
int poolSize = 10
ThreadFactory factory = new MyThreadFactory (Executors.defaultThreadFactory())
ExecutorService pool = Executors.newFixedThreadPool (poolSize, factory)
(1..100).each { i ->
pool.submit {
try {
MyDomainClass.withTransaction {
doSomeWork(i)
}
} catch (Exception e) {
log.error "error in job ${i}", e
}
}
}
MyThreadFactory creates threads in which the hibernate session is connected for the duration of the thread.
class MyThreadFactory implements ThreadFactory {
ThreadFactory delegate
PersistenceContextInterceptor persistenceInterceptor
MyThreadFactory (ThreadFactory delegate) {
this.delegate = delegate
ApplicationContext applicationContext = ApplicationHolder.getApplication().getMainContext()
persistenceInterceptor = applicationContext.getBean("persistenceInterceptor");
}
Thread newThread (Runnable work) {
return delegate.newThread {
persistenceInterceptor.init()
try {
work.run()
} finally {
persistenceInterceptor.flush()
persistenceInterceptor.destroy()
}
}
}
}
Everything seems to work, however the first time I run the batch job, I get the following error. (Subsequent tasks run without incident)
groovy.lang.MissingMethodException: No signature of method: static MyDomainClass.save() is applicable for argument types: (java.util.LinkedHashMap) values: [[flush:false]]
Possible solutions: save(), save(java.util.Map), save(java.lang.Boolean), wait(), any(), wait(long)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at ...
persitanceInterceptor MyDomainClass.withNewSession {} .
, GORM .
- , , ?
@fixitagain :
doSomeWork = { id ->
MyDomainClass a = MyDomainClass.findById (id)
a.value = lotsOfWork()
a.save()
}
, - , , "DomainClass.withTransaction(Closure)" .
, , , (-?).