在 MongoDB 副本集中读取自己的写入。随意一致性不起作用?

Read own writes in a MongoDB replicaset. Casual consistency not working?

我在 3 成员副本集中使用 mongodb,试图读取我自己的写入。但是,我似乎从我的读取中得到了过时的数据。根据 documentation,通过 read/write 和 "majority" 关注,它应该保证:

"Read operations reflect the results of write operations that precede them."

从 2018 年开始,this post 中也有同样的说法:

The causal read R1 with read concern majority waits to see T1 majority committed before returning success.

不过,我好像没那么幸运。下面的代码插入一个用户并立即尝试通过 ID 找到同一用户。这是在一个循环中完成的,在失败之前只需要 1-3 次迭代 "User not found".

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");
    }
}

我已经为 read/write 指定了 "Majority" 问题。为了测试这一点,我将 "Secondary" 指定为阅读首选项。如果我将 "Primary" 指定为读取首选项,这将永远不会失败(显然)。

我做错了什么?

首先,your link中描述的因果一致性需要在会话中执行操作。我没有在您的代码中看到会话使用。

其次,majority read concern 的意思是:

read concern "majority" guarantees that the data read has been acknowledged by a majority of the replica set members (i.e. the documents read are durable and guaranteed not to roll back).

这不能保证返回的数据是文档的最新版本。如果您正在进行辅助读取,您将获得截至该辅助节点的集群时间提交给大多数节点的数据,这可能滞后于主节点的集群时间。

根据 this note 你需要一个会话来获得与大多数阅读关注的因果一致性。