简体   繁体   中英

Spring MongoDB Inconsistent Persistence Issue

I'm making a web service for a game using Spring and MongoDB. 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() ):

//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():

//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():

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

And 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.

Now I make a request to /player/id , where id is a player's id. This gives me back a JSON encoding of the resulting Player object (using the same getPlayerByID() as above). If I make this request with the dead player's id, he comes back as alive.

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.

I'm currently running this on a Tomcat v7.0 server on localhost.

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!!!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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