Grails 如何使用GORM自动更新一组对象

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

我使用的是GORM standalone(groovyVersion='2.0.8',grailsVersion='2.2.4',gormVersion='1.3.7',h2Version='1.3.170'),并且有一个对象数据库,该数据库将经常进行并发修改

这些对象按一个属性“entry”分组,并具有另一个需要更新的属性“process_flags”。我想更新由相同条目定义的一组对象的所有process_标志设置。(这将向其他进程指示我正在处理这组对象。)

我目前正在尝试以下代码:

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离子。