Grails 2.3.7每次提交命令对象时都会更新乐观锁定版本

时间:2014-04-23 15:56:53

标签: grails gorm optimistic-locking

我有以下

def save(ACommand command){
  ...
}

@Validateable
class ACommand implements Serializable
{
  ADomainObject bundleDef
}

但每次调用save时,版本都会递增。因此,如果我打开两个浏览器并连续提交不同的值,而不是像我期望的那样第二次得到错误,则更新该值。

我也试过使用两个不同的会话,没有区别

更新

如果我使用断点并在另一个完成之前提交它可以正常工作。但是,如果我让第一个完成然后提交第二个没有刷新版本更新到更新的版本(我不想要),并且更改将继续。

更新2

  

当您执行更新时,Hibernate将根据数据库中的版本列自动检查版本属性,如果它们不同则会抛出StaleObjectException。如果一个处于活动状态,这将回滚事务。

per Grails这应该对我有用。

2 个答案:

答案 0 :(得分:0)

AFAIK,您需要自己检查版本并处理故障 - 它不会自动发生。您可以使用以下代码执行此操作:

/**
 * Returns a boolean indicating whether the object is stale
 */
protected boolean isStale(persistedObj, versionParam = params.version) {

    if (versionParam) {
        def version = versionParam.toLong()
        if (persistedObj.version > version) {
            return true
        }
    } else {
        log.warn "No version param found for ${persistedObj.getClass()}"
    }
    false
}

您可以通过此类

动作来呼叫isStale
def update() {
    Competition competition = Competition.get(params.id)

    if (isStale(competition)) {
        // handle stale object
        return
    }

    // object is not stale, so update it
}

答案 1 :(得分:0)

我不确定您期望发生什么,但您所描述的内容对我来说听起来不对,除非您的save()操作中的代码相关。

你不能指望Hibernate在这里做任何特别的事情。当调用save()动作时,使用Hibernate检索实例,进行变异然后保存。就Hibernate而言,这一切都很好。

处理此问题的一种方法是,在呈现用于编辑实体的表单时,将正在编辑的实体的版本呈现为隐藏的表单字段,该字段将在保存实体时提交。在从数据库中检索实体后的保存操作中,将其版本与从隐藏表单字段中检索的版本进行比较,如果它们不匹配,则您知道该实体在这两个步骤之间进行了修改,但您可以做出反应但是为您的应用程序。请注意,由于您的示例使用的是命令对象,因此在执行代码之前会对实体强加数据绑定。如果那不是您想要的,请不要使用命令对象。

我希望有所帮助。