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は休止セッションを有しているスレッドがスレッドの期間添付作成します。
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は可能な解決策としてsave(Map)を提案しているので、「添付」されています。保存している行を保存することはできますか? BTWのflushはデフォルトではfalseです。つまり、Hibernateセッションの終わりにフラッシュされます。 – fixitagain