在 MongoDB 中创建后偶尔会出现读取失败

Occasional read failures after create in MongoDB

我正在使用 Spring MongoTemplate 与我的 java 应用程序中的 MongoDB 实例集成。我正在 运行ning 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 偶尔(可能是 100 次执行中有 1 次)被分配一个空值.数据通过插入成功持久化。我已经能够在 savedEntity == null 上设置一个断点条件,当我到达该断点并通过我的 IDE 再次强制 findById 到 运行 时,它 returns 预期的结果(不为空)。

日志记录表明这些操作在同一线程上快速连续发生(创建 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

在我看来,读取操作发生在数据 "fully" 持久化之前,因此没有找到匹配的对象。但是不写原子性就意味着这不应该发生吗?

我担心我的读取会进入过时的辅助节点(因为我没有等待写入时的复制)所以我​​重新配置了我的 mongoTemplate 使其中只有主节点配置,但问题并没有消失。

如有任何答案、对 mongo 先写后读行为的说明或疑难解答提示,我们将不胜感激。

这个问题的根本原因是因为我是 运行 一个 3 节点副本集,而我的应用程序正在使用 readPreference=NEAREST。这意味着我可以在写入之后但在数据复制到辅助节点之前从辅助节点读取数据。对于此应用程序,需要 readPreference=PRIMARY。