8

I have been reading up on Write Concern in MongoDB. I understand that there are several levels that determine the level of guarantee that a write operation succeeded, with a performance trade-off for the higher you set this level. However, I am working in a C# environment, and I am trying to figure out how to use Write Concern there and what levels work best for certain situations. I already figured out how to collect the result of the check with a WriteConcernResult object, I am mainly interested in the levels themselves.

These are my questions:

How do I set the Write Concern level in C# for specific writes?

This answer suggests using the connection string, but this looks like a global setting, which I don't want, since some of the write operations I will be using are more "important" than others and I don't want to kill the performance. I noticed there's a WriteConcern class but the documentation isn't very detailed about its use (it's under MongoDB.Driver Namespace in the documentation).

In particular, how do I set it to "Journaled" or "Replica Acknowledged", seeing as it's "Acknowledged" by default?

What types of issues could get past the Write Concern check for each level?

For example: system crashes, power failures, network connection issues, etc. I am especially interested in something sneaking by that is not easily detected, as power failures and the like are very noticeable and we could estimate the time interval where operations may have failed and react accordingly.

Community
  • 1
  • 1
Augustin Popa
  • 1,423
  • 1
  • 19
  • 22

2 Answers2

4

For 2.x c# driver, you can use write concern in the following way:

var collection = db.GetCollection<Record>(collectionName)
    .WithWriteConcern(new WriteConcern(
        w: 1,
        wTimeout: default(TimeSpan?),
        fsync: true,
        journal: false));

then any updates to the db using this collection will use the passed write concern.

collection.InsertOne(...);
collection.ReplaceOne(...);
collection.UpdateMany(...);
and so on

There are several predefined write concerns e.g.

for very fast but unreliable updates:

var collection = db.GetCollection<Record>(collectionName)
    .WithWriteConcern(WriteConcern.Unacknowledged);

or for WriteConcern which is similar to the default (w=1)

var collection = db.GetCollection<Record>(collectionName)
    .WithWriteConcern(WriteConcern.W1);

or for acknowledge of majority members of the replica set

var collection = db.GetCollection<Record>(collectionName)
    .WithWriteConcern(WriteConcern.WMajority);

for details and more options please see the documentation here: https://mongodb.github.io/mongo-csharp-driver/2.7/apidocs/html/T_MongoDB_Driver_WriteConcern.htm

Aviko
  • 1,139
  • 12
  • 21
  • What is the default write concern for the C# driver? I thought it would be w=1 like it is for MongoDB but I never set a write concern and it seems to default to "majority"... Is this a bug or is it really "majority" for the C# driver?... – Asheq Reza Aug 21 '19 at 18:34
  • @AsheqReza: The c# driver is just an API for the mongodb server, so the wc you set in the c# code - simply sent to the mongodb server in the commands. similar to the impact that you have when you add { writeConcern: { w: "majority" } } to insert/update commands. see https://docs.mongodb.com/manual/core/replica-set-write-concern/ – Aviko Sep 04 '19 at 08:17
  • Does this add much speed increase, I have a single mongo instance and past 250mil records runs like a dog – Burf2000 May 14 '20 at 08:40
  • This fixed my problem. Not sure why I had to explicitly add `.WithWriteConcern(WriteConcern.WMajority)` as it was working prior to moving to fluent configuration in-lieu of annotations, but I did. Also it was part of my connection string already. Very strange. – Shawn Mar 10 '21 at 14:52
1

The operations in the MongoDB C# driver have overloads that accept a WriteConcern that you can get by using the class constructor or using a predefined static property:

var writeConcern = WriteConcern.W4;
writeConcern.Journal = true;
writeConcern.WTimeout = TimeSpan.FromMilliseconds(100);
new MongoClient().GetServer().GetDatabase("").GetCollection("").Insert(null, null, writeConcern);

This for example requires 3 replicas on top of the primary, hence W4, the Journal flag is turned on and the wtimeout is set to 100 ms.

i3arnon
  • 113,022
  • 33
  • 324
  • 344
  • Ok thanks for the information! Do you also know what types of issues could sneak through undetected for each level (specified in my second question above). I would like to have an idea of what levels to set for different operations to balance out performance with data integrity. EDIT: Also, is WriteConcern.W4 effectively setting the Write Concern level to "Replica Acknowledged", the highest level? If so, is the Journal flag even necessary? Doesn't the data get journaled before the replica acknowledged phase? – Augustin Popa Oct 31 '14 at 14:26
  • I don't really understand what do you mean by sneaking issues. If you use Unacknowledged then you would be unaware of errors, if you replicate to 2 instances out of 10 in your replica sets and these two fail your data is lost. – i3arnon Oct 31 '14 at 21:45
  • 1
    @AugPopa Replica Acknowledged is not really a level. Any w level higher than 1 would require replica acknowledgment, wmajority would as well. It sets the number of instances required (including the primary). The journal flag adds an unrelated requirement relevant only to the primary instance. More in the [documentation](http://docs.mongodb.org/manual/reference/write-concern/) – i3arnon Oct 31 '14 at 21:55
  • I tried using writeConcern.Journal = true, however it turned out it is read only. I guess that W[number] write concern level sets it the way it is supposed to be set. – user1635881 Sep 10 '15 at 08:14
  • 1
    @user1635881 this answer is relevant for the 1.x driver. Are you using the 2.x one? – i3arnon Sep 10 '15 at 08:16
  • @i3arnon Sorry, I forgot to mention that, I am using 2.x driver. – user1635881 Sep 10 '15 at 08:16