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

在MongoDB复制集中读取自己的写入。随意的一致性不起作用?,mongodb,mongodb-query,replicaset,Mongodb,Mongodb Query,Replicaset,我在一个三人副本集中使用mongodb,试图读取我自己写的东西。然而,我似乎从我的读取中得到了过时的数据。根据,通过使用“多数”关注点进行读/写操作,应保证: “读取操作反映它们之前的写入操作的结果。” 自2018年起,上述规定如下: 具有读关注多数的因果读R1在返回成功之前等待T1多数提交 然而,我似乎没那么幸运。下面的代码插入一个用户,并立即尝试通过ID查找同一个用户。这是在循环中完成的,只需1-3次迭代,然后失败为“未找到用户” IMongoCollection collection=Mo

我在一个三人副本集中使用mongodb,试图读取我自己写的东西。然而,我似乎从我的读取中得到了过时的数据。根据,通过使用“多数”关注点进行读/写操作,应保证:

“读取操作反映它们之前的写入操作的结果。”

自2018年起,上述规定如下:

具有读关注多数的因果读R1在返回成功之前等待T1多数提交

然而,我似乎没那么幸运。下面的代码插入一个用户,并立即尝试通过ID查找同一个用户。这是在循环中完成的,只需1-3次迭代,然后失败为“未找到用户”

IMongoCollection collection=MongoDatabase.GetCollection(“UserCollection”)
.WithReadConcern(ReadConcern.double)
.WithWriteConcern(WriteConcern.WMajority)
.WithReadPreference(ReadPreference.Secondary);
随机rnd=新随机();
while(true)
{
用户newUser=新用户
{
电子邮件=$“{rnd.Next(int.MinValue,int.MaxValue)}@gg.com”
};
collection.InsertOne(新用户);
if(newUser.Id==ObjectId.Empty)
{
抛出新异常(“Id为空”);
}
var findFluent=collection.Find(Builders.Filter.Eq(x=>x.Id,newUser.Id));
User foundUser=findFluent.FirstOrDefault();
if(foundUser==null)
{
抛出新异常(“未找到用户”);
}
}
我已经为读/写操作指定了“多数”关注点。为了测试这一点,我将“Secondary”指定为读取首选项。如果我将“Primary”指定为读取首选项,这将永远不会失败(显然)


我做错了什么?

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

第二,确切地说是指:

读取关注点“多数”保证读取的数据已被大多数副本集成员确认(即,读取的文档是持久的,并保证不会回滚)

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


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

从我对文档的阅读来看,它听起来像是
{read:“majority”}
应该在一个分布式逻辑时钟中工作。我会查看您的驱动程序代码,以确保您位于支持此功能的客户端之一,并查看您是否需要执行任何操作来创建会话。您是正确的。正如公关“D.SM”的回答,我不是在一个会话中进行操作,这解决了问题。您对会话的看法完全正确,谢谢。显然,我对此一无所知。然而,您所说的关于二次读取的内容并不完全正确。如果你写了一篇“多数”文章,然后又读了一篇“多数”文章,你就永远不会落后。辅助服务器将等待写操作传播。(参见我问题中的第二个链接)。在一个会话中,是的。
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");
    }
}