我正在使用GORM独立(groovyVersion ='2.0.8',grailsVersion ='2.2.4',gormVersion ='1.3.7',h2Version ='1.3.170')并拥有一个对象数据库经常进行并发修改。
这些对象按一个属性“entry”分组,并具有我需要更新的另一个属性“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
,根据此讨论:{ {3}}。请注意,此代码出现的类和方法都没有注释@Transactional
。
所以我的问题是如何在频繁并发访问的代码中最好地处理这种情况?是否有办法解决乐观锁定的失败?或者这是否需要通过一些悲观锁定来处理?如果是这样,它仍然可以用动态查找器处理吗?
答案 0 :(得分:0)
您要执行的操作是使用where
查询。 where
方法返回DetachedCriteria
实例,允许您执行批量更新:
Item.where { entry == firstItem.entry }
.updateAll(processFlags: Item.ProcessFlags.IN_PROCESS)