I am using mongodb in a 3-member replicaset, trying to read my own writes. However, I seem to be getting stale data back from my reads. According to the documentation, by doing read/write with "majority" concerns, it should guarantee that:
"Read operations reflect the results of write operations that precede them."
The same is stated in this post from 2018:
The causal read R1 with read concern majority waits to see T1 majority committed before returning success.
However, I can't seem to be so lucky. The code below inserts a user and instantly tries to find that same user by the ID. This is done in a loop and only takes 1-3 iterations before it fails with "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");
}
}
I have specified "Majority" concerns for both read/write. And I specify "Secondary" as read preference for the sake of testing this. If I specify "Primary" as the read preference, this will never fail (obviously).
What am I doing wrong?
First, the causal consistency described in your link requires performing operations in a session. I don't see session use in your code.
Second, majority read concern means, exactly:
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 does not guarantee that the data returned is the most recent version of a document. If you are doing a secondary read, you get the data that is committed to the majority of nodes as of the cluster time of that secondary, which could lag behind the primary's cluster time.
According to this note you need a session to get causal consistency with majority read concern.