我想在grails应用程序中创建特定类型的后台处理设置。在grails中的后台线程中调用Hibernate
- 甲固定大小线程池只存在
- 甲单个会话由每个线程维持该批次作业的持续时间
- 每个作业在单独的事务运行
我想开始工作如下:
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创建具有一个hibernate会话线程附为线程的持续时间。
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()
}
}
}
}
它似乎工作,但我会在第一次运行批处理作业时出现以下错误。 (后续作业运行无事故)
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 ...
我试图与MyDomainClass.withNewSession {}更换persitanceInterceptor,没有效果。
似乎GORM方法没有被注入到我的域类中。
任何人都可以看到我做错了什么,以及为什么再次运行批处理作业允许它成功?
@fixitagain为完整的工作采取这种形式:
doSomeWork = { id ->
MyDomainClass a = MyDomainClass.findById (id)
a.value = lotsOfWork()
a.save()
}
我相信丢失的存储是一个红色的鲱鱼,因为我想在包裹交易操作,然后得到一个错误说' DomainClass.withTransaction(Closure)'未定义。
看起来可能存在第一个作业无法运行的竞态条件,但所有后续作业成功运行后(东西?)已完成启动。
他在Grails生命周期的哪个阶段开始工作?这听起来像是在域名被动态方法等装饰之前发生的。 –
作业正在从控制器动作(现在)触发,所以在完成域的装饰之后就已经完成了。我应该注意到,如果我从主线程调用所有作业,则不会出现问题。 – Akusete
好吧,对我来说,GORM是“附加”的,因为它提出了保存(Map)作为可能的解决方案。你可以把你正在使用的保存行吗? BTW flush默认为false,这意味着它将在Hibernate会话结束时刷新... – fixitagain