Pode haver outras maneiras de fazer isso, mas uma abordagem é a versão de seus documentos e emitir atualizações apenas para a versão que o usuário leu anteriormente (ou seja, garantir que ninguém mais tenha atualizado o documento desde a última leitura). Aqui está um breve exemplo desta técnica usando 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}
nota acima, a chave "n" é 1, indicando que o documento foi atualizado
>>> 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}
aqui onde tentamos atualizar com a versão errada, a chave "n" é 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}
Observe que essa técnica depende do uso de gravações seguras, caso contrário, não obteremos uma confirmação indicando o número de documentos atualizados. Uma variação disso usaria o
findAndModify
comando, que retornará o documento ou None
(em Python) se nenhum documento correspondente à consulta foi encontrado. findAndModify
permite que você retorne a nova (ou seja, após a aplicação das atualizações) ou a versão antiga do documento.