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

时间:2014-05-30 22:12:32

标签: grails gorm concurrentmodification

我正在使用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.eachStaleObjectStateException,但我认为实际上是HibernateOptimisticLockingFailureException,根据此讨论:{ {3}}。请注意,此代码出现的类和方法都没有注释@Transactional

所以我的问题是如何在频繁并发访问的代码中最好地处理这种情况?是否有办法解决乐观锁定的失败?或者这是否需要通过一些悲观锁定来处理?如果是这样,它仍然可以用动态查找器处理吗?

1 个答案:

答案 0 :(得分:0)

您要执行的操作是使用where查询。 where方法返回DetachedCriteria实例,允许您执行批量更新:

 Item.where { entry == firstItem.entry }
     .updateAll(processFlags: Item.ProcessFlags.IN_PROCESS)