Случайные ошибки чтения после создания в MongoDB

Я использую Spring MongoTemplate для интеграции с экземпляром MongoDB в моем приложении Java. Я использую mongo версии 2.4.5 и spring-data-mongodb 1.2.3-RELEASE.

Я запускаю mongoDB в наборе реплик из 3 узлов, без сегментирования.

У меня есть код создания данных, который последовательно вызывает следующие две операции в одном потоке с WriteConcern=ACKNOWLEDGED:

mongoTemplate.insert(entity);
savedEntity = mongoTemplate.findById(entity.getId(), entity.getClass());

Я успешно запускаю это приложение в нескольких разных средах, но в одной среде savedEntity иногда (возможно, 1 из 100 выполнений) присваивается нулевое значение. Данные успешно сохраняются вставкой. Я смог установить точку останова, условную для saveEntity == null, и когда я нажму на эту точку останова и заставлю этот findById снова запуститься через мою IDE, он вернет ожидаемый результат (не нуль).

Ведение журнала указывает, что эти операции выполняются в быстрой последовательности в одном и том же потоке (создание 5):

2015-01-12 18:32:13,796 DEBUG [create 5] org.springframework.data.mongodb.core.MongoTemplate: Inserting DBObject containing fields: [_class, _id, guid, updated, added, version] in collection: persistentEntity
2015-01-12 18:32:13,798 DEBUG [create 5] org.springframework.data.mongodb.core.MongoTemplate: findOne using query: { "_id" : 4660192} in db.collection: MyDatabase.persistentEntity

Мне кажется, что операция чтения происходит до того, как данные были «полностью» сохранены, и поэтому соответствующий объект не найден. Но разве атомарность не означает, что этого не должно происходить?

Я беспокоился, что мое чтение будет устаревшим вторичным (поскольку я не жду репликации при записи), поэтому я перенастроил свой mongoTemplate, чтобы в его конфигурации был только основной узел, но проблема не исчезла.

Будем признательны за любые ответы, разъяснения о поведении монго при записи и чтении или советы по устранению неполадок.


person skelly    schedule 12.01.2015    source источник
comment
только вопрос, а зачем вам читать это так скоро после того, как вы это написали?   -  person unobf    schedule 12.01.2015
comment
ну, код предназначен для возврата объекта, который был сохранен, клиенту, отправившему запрос на его сохранение. Я думаю, что на самом деле нет веской причины снова вывести объект из персистентности... Я мог бы просто вернуть entity. Но в любом случае я ожидаю, что приведенный выше код будет работать.   -  person skelly    schedule 13.01.2015
comment
Есть разница: поле _id добавляется при вставке, когда его еще нет.   -  person Svante    schedule 20.01.2015
comment
Во всяком случае, для меня это звучит как ошибка либо в MongoDB, либо в драйвере Java.   -  person Svante    schedule 20.01.2015


Ответы (1)


Основная причина этой проблемы заключалась в том, что я запускал набор реплик из 3 узлов, а мое приложение использовало readPreference=NEAREST. Это означало, что потенциально я мог читать со вторичного узла после записи, но до того, как данные были реплицированы на вторичный. Для этого приложения требуется readPreference=PRIMARY.

person skelly    schedule 02.09.2015