Я использую автономный GORM (groovyVersion = '2.0.8', grailsVersion = '2.2.4', gormVersion = '1.3.7', h2Version = '1.3.170') и имею базу данных объектов, которые будут часто модификация.
Эти объекты сгруппированы по одному свойству «запись» и имеют другое свойство «process_flags», которое мне нужно обновить. Я хочу обновить все настройки process_flag группы объектов, определенных с помощью одной и той же записи. (Это укажет другим процессам, что я обрабатываю эту группу объектов.)
В настоящее время я пробую следующий код:
List<Item> res = null
int triesRemaining = 10 // try locking a group this many times
while (res==null && triesRemaining > 0) {
Item firstItem = Item.findByProcessFlags(Item.ProcessFlags.NEW)
if (firstItem==null) return null
res = Item.findAllByEntry(firstItem.entry)
try {
Item.withTransaction {transStatus->
res.each {it->
if (it.processFlags != Item.ProcessFlags.NEW) {
throw new StaleObjectStateException(Item.class.toString(),it.id)
}
it.processFlags = Item.ProcessFlags.IN_PROCESS
it.save(flush:true)
}
}
} catch (HibernateOptimisticLockingFailureException e) {
logger.debug("Caught HibernateOptimisticLockingFailureException. Trying new group.")
res = null
triesRemaining--
}
return res
Это приводит к распространению исключения вверх по стеку, помеченного как возникающее в res.each
и как StaleObjectStateException
, хотя я предполагаю, что на самом деле это HibernateOptimisticLockingFailureException
, согласно этому обсуждению: Как обрабатывать исключения GORM. Обратите внимание, что ни класс, ни метод, в котором появляется этот код, не имеют аннотации @Transactional
.
Итак, мои вопросы: как лучше всего справиться с этой ситуацией в коде с частым одновременным доступом? Есть ли способ сделать это с отловом сбоя оптимистической блокировки? Или это нужно обрабатывать с помощью какой-то пессимистической блокировки? И если да, то можно ли с этим справиться с помощью динамических искателей?