Il peut y avoir d'autres façons d'y parvenir, mais une approche consiste à versionner vos documents et à ne publier des mises à jour que pour la version que l'utilisateur avait précédemment lue (c'est-à-dire, assurez-vous que personne d'autre n'a mis à jour le document depuis sa dernière lecture). Voici un bref exemple de cette technique utilisant pymongo :
>>> db.foo.save({'_id': 'a', 'version': 1, 'things': []}, safe=True)
'a'
>>> db.foo.update({'_id': 'a', 'version': 1}, {'$push': {'things': 'thing1'}, '$inc': {'version': 1}}, safe=True)
{'updatedExisting': True, 'connectionId': 112, 'ok': 1.0, 'err': None, 'n': 1}
notez ci-dessus, la clé "n" est 1, indiquant que le document a été mis à jour
>>> db.foo.update({'_id': 'a', 'version': 1}, {'$push': {'things': 'thing2'}, '$inc': {'version': 1}}, safe=True)
{'updatedExisting': False, 'connectionId': 112, 'ok': 1.0, 'err': None, 'n': 0}
ici où nous avons essayé de mettre à jour avec la mauvaise version, la clé "n" est 0
>>> db.foo.update({'_id': 'a', 'version': 2}, {'$push': {'things': 'thing2'}, '$inc': {'version': 1}}, safe=True)
{'updatedExisting': True, 'connectionId': 112, 'ok': 1.0, 'err': None, 'n': 1}
>>> db.foo.find_one()
{'things': ['thing1', 'thing2'], '_id': 'a', 'version': 3}
Notez que cette technique repose sur l'utilisation d'écritures sécurisées, sinon nous n'obtenons pas d'accusé de réception indiquant le nombre de documents mis à jour. Une variante de cela utiliserait le findAndModify
commande, qui renverra soit le document, soit None
(en Python) si aucun document correspondant à la requête n'a été trouvé. findAndModify
vous permet de renvoyer la nouvelle (c'est-à-dire après l'application des mises à jour) ou l'ancienne version du document.