简体   繁体   English

Spring MongoDB不一致的持久性问题

[英]Spring MongoDB Inconsistent Persistence Issue

I'm making a web service for a game using Spring and MongoDB. 我正在使用Spring和MongoDB为游戏制作Web服务。 One of the features is that, every day, players can vote on one other player to kill. 功能之一是,每天,玩家可以投票杀死另一名玩家。 At the end the day, votes are tallied, and the player with the most votes is killed off. 一天结束时,将计算票数,并把票数最高的玩家杀死。 Here's the code for killing the most-voted-for player (inside a larger method called endDay() ): 这是杀死最投票的玩家的代码(在名为endDay()的更大方法中):

//mostVotes is the player's id in the database.
//Player is just a transient domain object
//playerDAO is a custom DAO that interfaces with MongoDB (see below)
Player accused = playerDAO.getPlayerByID(mostVotes);
logger.info(accused.getIsDead()); //This is false
doKill(accused);
logger.info(playerDAO.getPlayerByID(mostVotes).getIsDead()); //This is true

Here's getPlayerByID(): 这是getPlayerByID():

//mongoTemplate is a MongoOperations object
public Player getPlayerByID(String id) throws NoPlayerFoundException {
    Player p = mongoTemplate.findById(id, Player.class);
    if (p == null) {
        throw new NoPlayerFoundException(id);
    }
    return p;
}

And doKill(): 和doKill():

private void doKill(Player p) {
    p.setIsDead(true);
    playerDAO.updatePlayer(p);
}

And updatePlayer(): 和updatePlayer():

public void updatePlayer(Player p) {
    mongoTemplate.save(p);  
}

As you can see, when I ask for the player's status right after killing him (in endDay() ), he seems to be dead, which is what we want. 如您所见,当我杀死玩家之后(在endDay() )要求玩家的身份时,他似乎已经死了,这就是我们想要的。

Now I make a request to /player/id , where id is a player's id. 现在,我向/player/id发出请求,其中id是玩家的ID。 This gives me back a JSON encoding of the resulting Player object (using the same getPlayerByID() as above). 这给了我返回的Player对象的JSON编码(使用与上面相同的getPlayerByID() )。 If I make this request with the dead player's id, he comes back as alive. 如果我用死亡玩家的ID发出此请求,他将复活。

Further complicating this is that other updates go through fine across requests. 使此问题进一步复杂化的是,其他更新在所有请求中都可以顺利通过。 For example, certain players can kill other players without voting. 例如,某些玩家无需投票即可杀死其他玩家。 This killing uses the exact same Player , getPlayerByID() , doKill() , and updatePlayer() , and the victim's deadness is persisted. 这种杀死使用了完全相同的PlayergetPlayerByID()doKill()updatePlayer() ,并且受害者的死亡仍然存在。

I'm currently running this on a Tomcat v7.0 server on localhost. 我目前正在本地主机上的Tomcat v7.0服务器上运行此程序。

Fixed! 固定! Turns out I was later iterating through and updating an outdated list of players. 原来,我后来遍历并更新了过时的玩家列表。 So the killed player was accidentally resurrected. 因此,被杀死的玩家意外地复活了。

Moral of the story: be sure your domain objects are always current!!! 故事的寓意:请确保您的域对象始终是最新的!!!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM