让我们说我有以下模型:
public class Person
{
[BsonId]
public Guid Id { get; set; }
public string Name { get; set; }
public string Title { get; set; }
public DateTime ReceivedAt { get; set; }
}
我有N个线程执行“如果不存在,则插入”,如何确保只有一个线程在DB中插入文档。
我尝试过的是:
void test(DBContext context)
{
var person = new Person() { Id = Guid.NewGuid(), Name = "name", Title = "title", ReceivedAt = DateTime.Now };
Console.WriteLine(DateTime.Now);
var update = Builders<Person>.Update.Combine(
Builders<Person>.Update.SetOnInsert(y => y.Name, person.Name)
, Builders<Person>.Update.SetOnInsert(y => y.Title, person.Title)
, Builders<Person>.Update.SetOnInsert(y => y.ReceivedAt, person.ReceivedAt)
, Builders<Person>.Update.SetOnInsert(y => y.Id, person.Id));
var result = context.People.FindOneAndUpdateAsync<Person>(
x => x.Title == person.Title && x.Name == person.Name && x.ReceivedAt > person.ReceivedAt - TimeSpan.FromSeconds(10),
update,
new FindOneAndUpdateOptions<Person>() { IsUpsert = true,ReturnDocument = ReturnDocument.Before}).GetAwaiter().GetResult();
if (result?.Id != null)
{
Console.WriteLine("duplicate");
}
else
{
Console.WriteLine("first time");
}
}
并使用以下方法进行了测试:
DBContext context = new DBContext ();
for (int i = 0; i < 10; i++)
{
Task.Run(() => test(context));
}
但是上面的代码将多个文档插入到集合中,似乎FindOneAndUpdateAsync
不是原子的。
是否有办法实现只有一个线程将文档插入Mongodb中的集合?