Có thể có những cách khác để thực hiện điều này, nhưng một cách tiếp cận là phiên bản tài liệu của bạn và chỉ phát hành các bản cập nhật đối với phiên bản mà người dùng đã đọc trước đó (tức là đảm bảo rằng không ai khác đã cập nhật tài liệu kể từ lần đọc cuối cùng). Dưới đây là một ví dụ ngắn gọn về kỹ thuật này bằng cách sử dụng 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}
lưu ý ở trên, khóa "n" là 1, cho biết rằng tài liệu đã được cập nhật
>>> 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}
tại đây chúng tôi đã cố gắng cập nhật phiên bản sai, khóa "n" là 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}
Lưu ý rằng kỹ thuật này dựa vào việc sử dụng ghi an toàn, nếu không chúng tôi sẽ không nhận được xác nhận cho biết số lượng tài liệu được cập nhật. Một biến thể của điều này sẽ sử dụng findAndModify
lệnh này sẽ trả về tài liệu hoặc None
(bằng Python) nếu không tìm thấy tài liệu nào phù hợp với truy vấn. findAndModify
cho phép bạn trả lại phiên bản mới (tức là sau khi áp dụng các bản cập nhật) hoặc phiên bản cũ của tài liệu.