gpt4 book ai didi

database - 同时请求Grails org.hibernate.StaleObjectStateException

转载 作者:行者123 更新时间:2023-12-02 14:52:05 24 4
gpt4 key购买 nike

我有一个带有 Controller 的应用程序。执行 Controller 的操作会使用数据库字段进行更新。一次完成一个 Action ,就可以了。但是当我同时执行两个操作时,出现org.hibernate.StaleObjectStateException错误

Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)

我需要 Controller 能够处理同步 Action ,例如通过排队请求并顺序执行它们。有可能吗?还是我需要自己照顾一下?

(是否在这里使用 synchronized帮助?这是正确的方法吗?)

数据库是内存/文件,因为我只做很少的工作。不必运行全面数据库。

编辑:调用“层次结构”如下:

这是入口点- Controller 。
GameController
def doTurn() {
String login = params.login


// From stackoverflow
def c = Player.createCriteria()
def player = c.get {
eq "login", login
lock true
}

// def player = Player.findAllByLogin(login).get(0)
PlayerChoice choice = Utils.intToChoice(Integer.parseInt(params.choice))
int turnNumber = Integer.parseInt(params.turn)

gameFlowService.makeTurn(player, choice, turnNumber)

def res = new Utils().playerStateToJSON(player)
render res as JSON
}

它调用gameFlowService:
GameFlowService{
def makeTurn(Player player, PlayerChoice choice, int turnNumber) {
(...)
Game currentGame = player.currentGame
Turn lastTurn = currentGame.getLastTurn()
// I do stuff with Turn (if it exists) or create it
currentGame.createTurn()
currentGame.getLastTurn().makeChoice(player, choice)
if (currentGame!=null){
currentGame.save(flush: true, failOnError: true)
}
}

游戏:
Game {
Player player1
Player player2

int turnsToBePlayed

List turns
static hasMany = [turns: Turn]
static belongsTo = [tournament: Tournament]

public void createTurn() {
Turn turn = new Turn([game : this,
turnNumber: turns.size(),
player1 : player1,
player2 : player2,
choice1 : PlayerChoice.CHOICE_NOT_SET,
choice2 : PlayerChoice.CHOICE_NOT_SET,
points1 : 0,
points2 : 0])

this.addToTurns(turn)
this.save(flush: true, failOnError: true)
}
}

然后转:
class Turn {
int turnNumber
boolean completed = false

Player player1
Player player2

PlayerChoice choice1
PlayerChoice choice2

int points1
int points2

static belongsTo = [game: Game]

public void makeChoice(Player player, PlayerChoice playerChoice){
// This method only changes Turn's member variables
}
}

我只会在添加新的回合时保存Game实例-导致我相信Hibernate会自动保留任何进一步的更改。

尽管使用了锁,但我仍然遇到相同的错误(stacktrace表示它在Game: this.save(flush: true, failOnError: true)中在线发生)

编辑2:
我相信我的问题并不少见。 Controller 操作会导致数据库中的更改,并且需要以某种方式对其进行序列化。 Hibernate / Grails如何解决它?

最佳答案

考虑到2个同时访问数据库的线程,我认为您的问题如下:

  • A检索对象
  • B检索对象
  • 更新对象
  • 保存对象
  • B更新对象
  • B保存对象-> StaleObjectStateException

  • 从数据库中检索对象时,可以锁定该对象。这将导致“选择...进行更新”,请参阅以下链接以了解用法:

    http://grails.org/doc/latest/ref/Domain%20Classes/lock.html

    但是为了避免出现任何竞争情况,您必须使用lock方法作为获取方法,如下所示:
    def airport = Airport.lock(10) // lock for update
    airport.name = "Heathrow"
    airport.save()

    如果必须查询对象,则可以在Criteria中使用锁。

    在条件示例中:
    def c = Airport.createCriteria()
    c.get {
    eq "name", name
    lock true
    }

    关于database - 同时请求Grails org.hibernate.StaleObjectStateException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24954632/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com