Grails 如何使用GORM自动更新一组对象
我使用的是GORM standalone(groovyVersion='2.0.8',grailsVersion='2.2.4',gormVersion='1.3.7',h2Version='1.3.170'),并且有一个对象数据库,该数据库将经常进行并发修改 这些对象按一个属性“entry”分组,并具有另一个需要更新的属性“process_flags”。我想更新由相同条目定义的一组对象的所有process_标志设置。(这将向其他进程指示我正在处理这组对象。) 我目前正在尝试以下代码:Grails 如何使用GORM自动更新一组对象,grails,gorm,concurrentmodification,Grails,Gorm,Concurrentmodification,我使用的是GORM standalone(groovyVersion='2.0.8',grailsVersion='2.2.4',gormVersion='1.3.7',h2Version='1.3.170'),并且有一个对象数据库,该数据库将经常进行并发修改 这些对象按一个属性“entry”分组,并具有另一个需要更新的属性“process_flags”。我想更新由相同条目定义的一组对象的所有process_标志设置。(这将向其他进程指示我正在处理这组对象。) 我目前正在尝试以下代码: List
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
List res=null
int-triesRemaining=10//尝试多次锁定组
while(res==null&&triesRemaining>0){
Item firstItem=Item.findByProcessFlags(Item.ProcessFlags.NEW)
if(firstItem==null)返回null
res=Item.findAllByEntry(firstItem.entry)
试一试{
Item.withTransaction{transStatus->
res.each{it->
if(it.processFlags!=Item.processFlags.NEW){
抛出新的StaleObjectStateException(Item.class.toString(),it.id)
}
it.processFlags=Item.processFlags.IN_进程
it.save(刷新:true)
}
}
}捕获(HibernateOptimisticLockingFailureException e){
debug(“捕获了HibernateOptimisticLockingFailureException。正在尝试新组。”)
res=null
特里斯雷宁--
}
返回res
这会导致异常向堆栈上传播,标记为发生在res.each
和StaleObjectStateException
,尽管我认为实际上是一个HibernateOptimisticLockingFailureException
,如下所述:。请注意,此代码出现的类和方法都不是空的ated@事务性
因此,我的问题是如何在频繁并发访问的代码中最好地处理这种情况?有没有办法捕获乐观锁定的失败?或者这需要用一些悲观锁定来处理?如果有,它仍然可以用动态查找器来处理?您想要做的是使用
where
quey.where
方法返回一个DetachedCriteria
实例,允许您执行批更新:
Item.where { entry == firstItem.entry }
.updateAll(processFlags: Item.ProcessFlags.IN_PROCESS)
需要注意的一项非常重要的内容。Grails中的PatchedDefaultEventListener类将异常记录为错误,然后重新引发异常。这显示在日志中,有点混乱,因为它看起来像是一个异常被进一步捕获,但不是。引发的异常是HibernateOptimisticLockingFailureExcept离子。