0

I am using C++/Cli to work with mongoDB latest C# driver compiled as a dll. I use an instance of the driver in the C++ code.

I have tried many times. If I build more than one threads, each trying to update a document in the same collection, it seems only one thread will succeed. When I set a sleep time for the threads, it seems to work OK. But I need to concurrently update thousands of documents in short time, setting a sleep time is not a valid method.

Below is how the thread is started:

void updateKOOnMongo(int i, int k) {
    time_t tn = time(NULL);
    Sleep(max(1, (lastkoupdatetime - tn + 2) * 1000));
    lastkoupdatetime = time(NULL);
    MongoUpdates ^mgudt = gcnew MongoUpdates(i, k);
    Thread ^updateko = gcnew Thread(gcnew ThreadStart(mgudt, &MongoUpdates::UpdateKO));
    updateko->Start();
}

Here is the function in MongoUpdates:

    void MongoUpdates::UpdateKO {
        mongoImp->updateKO(i, k);
    }

mongoImp is an instance of the mongoDB C# driver compiled as dll.

Below is the code in the C# driver:

    public static async void updateKO(int i, int k)
    {
        await updateKOdr(i, k);
    }

    static async Task updateKOdr(int i, int k)
    {
        string col = "ko." + i.ToString();
        var collection = _database.GetCollection<BsonDocument>(col);
        var builder = Builders<BsonDocument>.Filter;
        var filter = builder.Eq("a", i) & builder.Lte("lf", k);
        var update = Builders<BsonDocument>.Update.Set("status", 0);
        var result = await collection.UpdateOneAsync(filter, update);
    }

If I remove the following part:

time_t tn = time(NULL);
Sleep(max(1, (lastkoupdatetime - tn + 2) * 1000));
lastkoupdatetime = time(NULL);

It almost always fails if two or more threads work on the same collection at the same time. Please help.

Harold
  • 33
  • 5

1 Answers1

0

I figured out the problem was that I created a new instance of the collection in every update operation. This is bad and I didn't notice that since the code was written long time ago when I was quite new to mongoDB. The mongoDB collection is thread safe so I should define it at global level like this:

protected static IMongoCollection<BsonDocument> _collection;

So I can use it without creating a new instance of it every time. I just need to do this:

if (_collection == null) {
   _collection = _database.GetCollection<BsonDocument>("ko." + i.ToString());
}
Harold
  • 33
  • 5