2

我有一个包含许多可行任务实体的任务列表实体,并且某些任务可以“关闭”任务列表。

class TaskList {
    ...
    static hasMany = [
        tasks: Task
    ]
}

class Task {
    ...
    static belongsTo = [taskList: TaskList]
}

现在,当更新任务并且它可以“关闭”任务列表时,我会TaskListService调用closeList()

class TaskListService {
    def closeList(TaskList taskList) {
        taskList.status = "CLOSED"
        taskList.save()
    }
}

// TaskController pseudo-update
def update () {
    Task taskInstance = Task.get(params.id)
    //... do something with the taskInstance
    taskListService.closeList(taskInstance.taskList)
}

我的问题是当用户在更新任务列表实体时TaskListService更新它。

class TaskListController {
    def update () {
        TaskList taskListInstance = TaskList.get(params.id)
        //... do some stuff
        taskListInstance.properties = params
        taskListInstance.save(flush:true)
    }
}

org.hibernate.StaleObjectStateException:行已被另一个事务更新或删除(或未保存的值映射不正确):[com.giotta.TaskList#1]

如何避免此版本冲突?

4

1 回答 1

8

如果您期望并发编辑,则必须使用显式锁定。您正在使用乐观锁定,之所以如此命名,是因为您希望不会有并发编辑时使用它,并且在发生这种情况的极少数情况下您可以处理问题。

使用lock()方法而不是get()方法,然后进行更新。请注意,锁定仅在事务中有意义,因此将 id 传递给服务而不是整个实例。

class TaskListService {
    def closeList(long taskListId) {
        TaskList taskList = TaskList.lock(taskListId)
        taskList.status = "CLOSED"
        taskList.save()
    }
}

// TaskController pseudo-update
def update () {
    Task taskInstance = Task.get(params.id)
    //... do something with the taskInstance
    taskListService.closeList(taskInstance.taskListId)
}

这里我使用taskListId动态属性。您可能需要将其更改为taskInstance.taskList.id

于 2013-02-06T21:00:52.927 回答