By looking at this official documentation it seems that there are basically three types of errors thrown by the MongoDB C# driver:
- errors thrown when the driver is not able to properly select or connect to a Server to issue the query against. These errors lead to a
TimeoutException
- errors thrown when the driver has successfully selected a Server to run the query against, but the server goes down while the query is being executed. These errors manifest themselves as
MongoConnectionException
- errors thrown during a write operations. These errors leads to
MongoWriteException
orMongoBulkWriteException
depending on the type of write operation being performed.
I'm trying to make my software using MongoDB a bit more resilient to transient errors, so I want to find which exceptions are worth retry.
The problem is not implementing a solid retry policy (I usually employ Polly .NET for that), but instead understanding when the retry makes sense.
I think that retrying on exceptions of type TimeoutException
doesn't make sense, because the driver itself waits for a few seconds before timing out an operation (the default is 30 seconds, but you can change that via the connection string options). The idea is that retry the operation after you have waited for 30 seconds before timing out is probably a waste of time. For instance if you decide to implement 3 retries with 1 second of waiting time between them, it takes up to 93 seconds to fail an operation (30 + 30 + 30 + 1 + 1 + 1). This is a huge time.
As documented here retrying on MongoConnectionException
is only safe when doing idempotent operations. From my point of view, it makes sense to always retry on these kind of errors provided that the performed operation is idempotent.
The hard bit in deciding a good retry strategy for writes is when you get an exception of type MongoWriteException
or MongoBulkWriteException
.
Regarding the exceptions of type MongoWriteException
is probably worth retrying all the exceptions having a ServerErrorCategory
other than DuplicateKey
. As documented here you can detect the duplicate key errors by using this property of the MongoWriteException.WriteError
object.
Retrying duplicate key errors probably doesn't make sense because you will get them again (that's not a transient error).
I have no idea how to handle errors of type MongoBulkWriteException
safely. In that case you are inserting multiple documents to MongoDB and it is entirely possible that only some of them have failed, while the others have been successfully written to MongoDB. So retrying the exact same bulk insert operation could lead to write the same document twice (bulk writes are not idempotent in nature). How can I handle this scenario ?
Do you have any suggestion ?
Do you know any working example or reference regarding retrying queries on MongoDB for the C# driver ?