2016-09-07 67 views
0

假設我有一個簡單的對象併發更改在異步MongoDB中(C#)

現在,我有兩個異步更新操作定義爲例如:

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#驅動程序,所有最新版本。

回答

0

我認爲這不是你的查詢問題,因爲mongodb保證原子性和併發控制看看這個link更多。

你的問題來自於如何安排任務我懷疑。 看看這個例子,如果你不等待Parallel.Invoke的結果,那麼你的查詢將不會被執行,因爲這個過程將在任務執行之前退出。所以,如果你添加Console.ReadLine()你的進程將被封鎖,允許蒙戈運行的任務

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,看看什麼的怎樣呢?

+0

會像collection.UpdateOneAsync(F,U).Result正常工作,然後它會強制操作完成?基本上使其成爲同步操作? – Thomas