動的ファインダーで古いオブジェクトの例外を一貫してスローするバッチ ジョブがあります。この仕事のために ORM ソリューションを実行しないのが理想ですが、仕方がありません。例外は、FormulaBatchPopulatorService から呼び出されている FormulaTagService で発生します。このアプリケーションは、1 つのデータベースを使用して 2 つのサーバーで実行されています。1 台のサーバーでバッチ処理を実行するだけです。
私の質問は次のとおりです。a) 特定のトランザクション中にオブジェクトに変更が加えられていないドメイン オブジェクト インスタンスが生成される単純な select ステートメントが、最終的にセッション内で永続化され、古いオブジェクト例外が発生するのはなぜですか? b) Formula.tags で行われている並べ替えがトランザクションの最後に保持されている可能性はありますか? そのため、他の誰かが別のサーバーで式を変更している場合、staleobjectexception が発生しますか?
サービスを読み取り専用に変更しましたが、古いオブジェクトの例外が引き続き発生することに注意してください。どんな助けでも大歓迎です。
数式タグ サービス
@Cacheable("formulaJob")
def getFormulaByTeacherTagsOrDefaultBatchJob(Long evaluationTemplateId, List teacherTags) {
Long formulaByTagsId = existsFormulaWithSameTagsBatchJob(evaluationTemplateId, teacherTags)
if (DefaultFormulaForEvaluationTemplate.get(evaluationTemplateId) == null && formulaByTagsId ==
null) {
return null;
}
Long defaultFormulaId = DefaultFormulaForEvaluationTemplate.get(evaluationTemplateId).formulaId
return formulaByTagsId ?: defaultFormulaId
}
def existsFormulaWithSameTagsBatchJob(Long evaluationTemplateId, List tags){
// LINE BELOW THROWING STALE OBJECT EXCEPTIONS
def formulas = Formula.findAllByExtEvaluationTemplateIdAndIsActive(evaluationTemplateId, true)
for (Formula formula: formulas) {
def formulaTags = formula.tags
if (existsTagMatchIgnoringBlankTags(tags, formulaTags)) {
def id = formula.id
formula.discard()
return id
}
}
}
@CacheEvict(value='formulaJob', allEntries=true)
def resetTags(){
}
def existsTagMatchIgnoringBlankTags(List tagsToCompare, List tagsExisting) {
if (!tagsToCompare || !tagsExisting) {
return false
}
else {
return tagsToCompare?.sort() == tagsExisting?.sort()
}
}
FormulaBatchPopulatorService スニペット
//Doing this below to improve performance of batch processing
if(index%250==0){
cleanUpGorm()
formulaTagService.resetTags() //cache-evict in formulatagservice
}
def cleanUpGorm(){
def session = sessionFactory.currentSession
session.flush()
session.clear()
propertyInstanceMap.get().clear()
}