我正在3成员副本集中使用mongodb,试图读取我自己的内容。但是,我似乎从读取中获取了过时的数据。根据documentation,通过对“多数”问题进行读/写,它应保证:
“读取操作反映了在其之前的写入操作的结果。”
从2018年起this post中也有相同说明:
具有多数读关注度的因果读R1等待返回成功的T1多数已提交。
但是,我似乎不太幸运。下面的代码插入一个用户,并立即尝试通过ID查找该用户。这是循环执行的,并且在失败并显示“找不到用户”之前只需要进行1-3次迭代。
IMongoCollection<User> collection = MongoDatabase.GetCollection<User>("UserCollection")
.WithReadConcern(ReadConcern.Majority)
.WithWriteConcern(WriteConcern.WMajority)
.WithReadPreference(ReadPreference.Secondary);
Random rnd = new Random();
while (true)
{
User newUser = new User
{
Email = $"{rnd.Next(int.MinValue, int.MaxValue)}@gg.com"
};
collection.InsertOne(newUser);
if (newUser.Id == ObjectId.Empty)
{
throw new Exception("Id is empty");
}
var findFluent = collection.Find(Builders<User>.Filter.Eq(x => x.Id, newUser.Id));
User foundUser = findFluent.FirstOrDefault();
if (foundUser == null)
{
throw new Exception("User not found");
}
}
我已为读/写都指定了“多数”关注点。为了测试这一点,我将“ Secondary”指定为读取首选项。如果我将“ Primary”指定为读取首选项,这将永远不会失败(显然)。
我在做什么错?
首先,your link中描述的因果一致性要求执行会话中。我看不到您的代码中使用会话。
第二,majority read concern的意思是:
读取关注点“多数”保证大多数副本集成员已确认读取的数据(即,读取的文档是持久的并且保证不会回滚)。
这不保证返回的数据是文档的最新版本。如果您正在执行辅助读取,则将获取到该辅助节点的群集时间之前已提交给大多数节点的数据,这可能会落后于主要节点的群集时间。
根据this note,您需要一个会话以确保大多数阅读方面的因果一致性。