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

时间:2015-01-12 18:56:18

标签: mongodb spring-mongo

我使用Spring MongoTemplate与我的java应用程序中的MongoDB实例集成。我正在运行mongo版本2.4.5和spring-data-mongodb 1.2.3-RELEASE。

我在3节点副本集中运行mongoDB,没有分片。

我有数据创建代码,在同一个线程上顺序调用以下两个操作,WriteConcern = ACKNOWLEDGED:

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

我在几个不同的环境中成功运行此应用程序,但在一个环境中, savedEntity 偶尔(可能是100次执行中的1次)被分配一个空值。插入成功地保留了数据。我已经能够设置一个以savedEntity == null为条件的断点,当我点击该断点并强制findById再次通过我的IDE运行时,它返回预期的结果(不为null)。

日志记录表明这些操作在同一个线程上快速连续发生(创建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只在其配置中有主节点,但问题不会消失。

任何答案,关于mongo写回读行为的说明或疑难解答提示都将不胜感激。

1 个答案:

答案 0 :(得分:0)

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

相关问题