Search code examples
mongodbdata-consistency

Saving only modified fields


I am working on a game where a player is switched between servers based on their location in the game world to give the illusion of a single server while maintaining scalability. When a player joins the server their data is loaded from a database (MongoDB) and when they quit or change server their data is saved.

My problem arises from cases where a players data is modified from a separate server from the player which needs to happen occasionally. The data in the database is changed but when the player leaves or changes server the data is overwritten: Example Image

To solve this problem I was thinking of storing only modified data as usually the data you want is the most recently changed. However when trying to find ways to do this I have noticed a lack of cases where this has been done. Is there any good reasons not to do this and use another method to ensure modified data is not overwritten? The only problem I could think of is data consistency where fields are updated and only some of them are overwritten potentially putting the player in an invalid state, which could be avoided fairly easily by updating all dependent fields together.

If there any other reasons against persisting only a selection of an object or any other ways to solve this problem that doesn't introduce any major problems I would love to hear of them.


Solution

  • This is a classic example of underlying state change between DB and code.

    Add an integer to your player profile/data document; call it v. Let's assume v = 6.

    When the player joins, the server loads the record. The server knows it's "local" view of the data is v = 6. When the player leaves, the code will call

    findAndModify({query: {"userID":"ID1","v":6}, update: {"$inc": { v: 1}, "$set": { fldtochange: newval, anotherfldtochange: newval2  } } });
    

    We show literal 6 here for simplicity but it would be a variable populated during the server load. This command will succeed ONLY if the original value of v = 6 is intact. If someone has changed it, no update will occur. You can take a variety of paths to recover including a re-read of the data and doing a delta to the state in your local server. If v = 6 is still there, it is atomically incremented +1 (e.g. to 7) and the rest of the fields set with new values.