2

実行可能なタスクエンティティが多数あるTaskListエンティティがあり、特定のタスクでTaskListを「閉じる」ことができます。

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)
}

私の問題は、ユーザーが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 に答える