簡體   English   中英

異步MongoDB(C#)中的並發更改

[英]Concurrent changes in Async MongoDB (C#)

假設我有一個簡單的對象:

class A
{
    int _id;
    int V1;
    int V2;
}

還有一個MongoDB表,其中包含以下內容:

現在,我定義了兩個異步更新操作,如下所示:

void UpdateV1(int id, int V)
{    
    var F = Builders<A>.Filter.Eq(_ => _._id, Id);
    var U = Builders<A>.Update.Set(_ => _.V1, V);
    Mongo.Driver.UpdateOneAsync(F, U);
}

void UpdateV2(int id, int V)
{    
    var F = Builders<A>.Filter.Eq(_ => _._id, Id);
    var U = Builders<A>.Update.Set(_ => _.V2, V);
    Mongo.Driver.UpdateOneAsync(F, U);
}

如果我運行以下命令:

UpdateV1(1, 10);

UpdateV2(1, 20);

在不同的線程上,但大致同時發生了什么?

我會得到:

  • 僅V1或V2已更改的記錄?
  • V1和V2均已更改的記錄?

我之所以這樣問,是因為我們有一個很奇怪的錯誤,它看起來像第一個選擇是發生了什么,但是預期的結果顯然是最后一個。

當我們進行阻塞調用時,這些問題開始消失,但這也可能是副作用。

這是使用C#驅動程序的所有最新版本。

我認為這不是查詢的問題,因為mongodb保證原子性和並發控制更多地查看了此鏈接

我懷疑您的問題來自如何安排任務。 如果您不等待Parallel.Invoke的結果,請看以下示例。調用不會被執行,因為在執行任務之前該過程將退出。 因此,如果您添加Console.ReadLine()您的進程將被阻止,從而允許mongo運行任務

namespace ConsoleApplication1
{
    class Program
    {
       static MongoClient mongoClient = new MongoClient();
        static IMongoDatabase databaseBase = mongoClient.GetDatabase("dbTest", null);
        static IMongoCollection<A> collection = databaseBase.GetCollection<A>("tests", null);
        static void Main(string[] args)
        {

            var a = new A
            {
                _id = 1,
                V1 = 0,
                V2 = 0
            };

            Parallel.Invoke( ()=> { var res=UpdateV1(1, 10).Result; },  ()=> { var res =  UpdateV2(1, 20).Result; });
            //Console.ReadLine(); 




        }
        static async  Task<long> UpdateV1(int id, int V)
        {
            var F = Builders<A>.Filter.Eq(a => a._id, id);
            var U = Builders<A>.Update.Set(a => a.V1, V);
            var result = await collection.UpdateOneAsync(F, U);
            return result.ModifiedCount;  
        }

        static async Task<long> UpdateV2(int id, int V)
        {
            var F = Builders<A>.Filter.Eq(_ => _._id, id);
            var U = Builders<A>.Update.Set(_ => _.V2, V);
            var result = await collection.UpdateOneAsync(F, U);
            return result.ModifiedCount;
        }


    }
    class A
    {
       public  int _id;
       public   int V1;
       public  int V2;
    }
}

可能您UpdateOneAsync要用UpdateOne替換UpdateOneAsync並查看發生了什么?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM