НЕТ Гарантия ACID для NOSql, то как обеспечить последовательность?
Например, для поиска и сохранения документа в MongoDB:
Article article1 = mongoOperation.findOne(new Query(Criteria.where("_id").is(1)), Article.class);
mongoOperation.save(article.setAttrA("A"));
Article article2 = mongoOperation.findOne(new Query(Criteria.where("_id").is(1)), Article.class);
mongoOperation.save(article.setAttrB("B"));
По умолчанию _id является первичным ключом, поэтому документы article1 и article2 совпадают.
Удастся ли получить устаревший документ для article2, для которого attrA еще не установлено значение A, поскольку в теоретическом отношении MongoDB не следует свойствам ACID.
1 ответ
Да, второй запрос может вернуть тот же документ перед применением сохранения.
На самом деле это весьма вероятно, если вы используете асинхронный API, синхронный API с небезопасной записью или предпочитаете чтение, которое предпочитает вторичную часть набора реплик (который обычно отсутствует за несколько секунд).
Что вы можете сделать, чтобы обнаружить и обработать конфликты редактирования, так это добавить идентификатор редакции к каждой статье, который вы увеличиваете на единицу при каждом редактировании. Когда вы обновляете статью, вы используете обновление вместо сохранения, например так:
article.revision++;
writeResult = db.articles.update(
{ _id: article._id, revision: article.revision -1 },
article,
{ writeConcern: WriteConcern.ReplicaAcknowledged}
);
Когда кто-то отредактирует статью, статья со старым идентификатором ревизии больше не будет в базе данных, и вы получите writeResult.nModified == 0
,