gpt4 book ai didi

c# - MongoDb C# 驱动程序在一个原子操作中更新多个文档

转载 作者:行者123 更新时间:2023-12-03 15:59:06 34 4
gpt4 key购买 nike

我想问一下下面的代码是否会在一个原子操作中执行。我正在使用 mongodb C# 驱动程序。

该方法的输入是我要更新的对象的 id 列表。

public void Update(IEnumerable<string> ids)
{
var query = Query<T>.Where(t => ids.Contains(t.Id));
var update = Update.Set("Modified", DateTime.Now); //this is just example of update

var options = new MongoUpdateOptions {Flags = UpdateFlags.Multi};

Collection.Update(query, update, options);
}

当我有数百万份文档需要更新时,我对这个案例很感兴趣。如果本次更新期间出现故障(电源或硬件问题),会发生什么情况?数据库会处于一致状态吗?

谢谢。

最佳答案

要求

MongoDB >= 4.0C# 驱动程序 >= 2.7这是我是如何做到的...

TL;DR

转到“示例代码”

<小时/>

session

在我的 DbContext 类中,我可以访问我的客户端 (IMongoClient),我定义了 session :

public IClientSessionHandle StartSession()
{
return _client.StartSession(new ClientSessionOptions());
}

public async Task<IClientSessionHandle> StartSessionAsync()
{
return await _client.StartSessionAsync(new ClientSessionOptions());
}

正如文档所述,它们能够一个接一个地执行多个交易,只要这些交易一个接一个地到来

A session is used to group together a series of operations that are related to each other and should be executed with the same session options. Sessions are also used for transactions.

这些 session 表示,一旦您结束操作,它们就应该关闭...

所以你实际上应该像下面这样写,或者根据你的场景执行手动处理:

// db is what i named my context, where i defined all my collections and database related stuffs. 
// if you have direct access to client, you can call `StartSession/Async` exactly over the `client` object
using(var session = _db.StartSessionAsync()) {
//... All transactional code will go here
}
// Here, on ending the block, Will automatically call `Dispose` method, and the object will no longer exists

通过 session 对象

交易

Transactions are started, committed or aborted using methods of IClientSession. A session can only execute one transaction at a time, but a session can execute more than one transaction as long as each transaction is committed or aborted before the next one is started.

在此步骤中,您需要在实际对数据库执行更改之前启动事务...

session.StartTransaction();

session 开始后,您应该执行交易,最后......

如果过程成功,您应该调用:

session.CommitTransaction();

否则需要回滚

session.AbortTransaction();

示例代码

正如你所看到的,我在 mongodb 上有两个写操作,还有另一个外部进程,这对我的情况至关重要,我需要这三个进程一起执行,..前两个由事务管理,并且只要第三个不会抛出异常,数据库应该保持其新状态。

bool error;
using (var session = await _db.StartSessionAsync())
{
session.StartTransaction();

try
{
var deletedImage = _db.GetUserStore<ApplicationUser>().CollectionInstance.UpdateOneAsync(
Builders<ApplicationUser>.Filter.Where(w => w.Id == userId),
Builders<ApplicationUser>.Update.Pull(x => x.ProfilePictures, photoFromRepo));

await _db.ProfilePicture().DeleteAsync(new ObjectId(photoFromRepo.ImageId));

if (photoFromRepo.CloudinaryPublicId != null)
{
var deleteParams = new DeletionParams(photoFromRepo.CloudinaryPublicId);
var result = _cloudinary.Destroy(deleteParams);
if (result.Result == "ok")
{
// ignore
}
else
{
throw new Exception("Cannot delete file from cloud service...");
}
}

await session.CommitTransactionAsync();
error = false;
}
catch (Exception ex)
{
await session.AbortTransactionAsync();
error = true;
}
}

这个有用吗?支持多个集合吗?只有上帝知道,我是根据文档和今天早些时候在回家的路上看到的一些示例以及我认为可能是正确的和可能的来写这篇文章的......

附加说明:

有一些选项可以传递 session ,其中一个选项控制读/写问题,另一个选项控制在执行事务之前应该提前多少数据(这是什么意思?我自己没有明白,如果您明白,请编辑我的帖子)

public class ClientSessionOptions
{
public bool? CausalConsistency { get; set; }
public TransactionOptions DefaultTransactionOptions { get; set; }
}

public class TransactionOptions
{
public ReadConcern ReadConcern { get; };
public ReadPreference ReadPreference { get; };
public WriteConcern WriteConcern { get; };

public TransactionOptions(
Optional<ReadConcern> readConcern = default(Optional<ReadConcern>),
Optional<ReadPreference> readPreference = default(Optional<ReadPreference>),
Optional<WriteConcern> writeConcern = default(Optional<WriteConcern>));

public TransactionOptions With(
Optional<ReadConcern> readConcern = default(Optional<ReadConcern>),
Optional<ReadPreference> readPreference = default(Optional<ReadPreference>),
Optional<WriteConcern> writeConcern = default(Optional<WriteConcern>))
}

关于c# - MongoDb C# 驱动程序在一个原子操作中更新多个文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19357887/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com