【问题标题】:multiple document transaction not working in c# using mongodb 4.08 community server使用 mongodb 4.08 社区服务器的多文档事务在 c# 中不起作用
【发布时间】:2019-09-16 01:59:03
【问题描述】:

我需要使用 mongodb 事务更新多个文档,mongodb 社区服务器版本是 4.08,.net 的 mongodb 驱动程序是 2.9 beta(也尝试过 2.8)。通过调试,我可以看到它执行了'session.AbortTransaction();',但数据仍然被插入。

var client = new MongoClient(_config.GetConnectionString(ProductMongoDBContext.DATABASE_CONNECTION_STRING));
var session = client.StartSession();

try
{
    session.StartTransaction();
    //var database = session.Client.GetDatabase(ProductMongoDBContext.DATABASE_NAME);
    var orders = session.Client.GetDatabase(ProductMongoDBContext.DATABASE_NAME).GetCollection<DALOrder>(ProductMongoDBContext.TABLE_NAME_ORDER);
    var products = session.Client.GetDatabase(ProductMongoDBContext.DATABASE_NAME).GetCollection<DALProduct>(ProductMongoDBContext.TABLE_NAME_PRODUCT);

DateTime dtNow = DateTime.Now.ToUniversalTime();
await orders.InsertOneAsync(new DALOrder
{
    ID = order.ID,
    ProductID = Guid.Parse(order.ProductID),
    Size = order.Size,
    Taste = order.Taste,
    TextOnCake = order.TextOnCake,
    Consignee = order.Consignee,
    ConsigneeAddress = order.ConsigneeAddress,
    ConsigneePhone = order.ConsigneePhone,
    DeliveryTime = order.DeliveryTime.ToUniversalTime(),
    DeliveryWay = order.DeliveryWay,
    OrderDepartment = order.OrderDepartment,
    Remarks = order.Remarks,
    State = OrderState.New.ToString(),
    CreatedTime = dtNow,
    UpdatedTime = dtNow
});

// After order created, decrease product inventory by one
var productInfo = products.Find<DALProduct>(p => p.ID.ToString().Equals(order.ProductID)).FirstOrDefault();
productInfo.Inventory -= 1;
await products.ReplaceOneAsync<DALProduct>(p => p.ID.ToString().Equals(order.ProductID), productInfo);

session.CommitTransaction();

return true;
}
catch (Exception e)
{
    session.AbortTransaction();
    order.Message = e.Message;
}

预计插入的订单数据可以回滚,实际结果是数据已经插入db。

顺便说一句,错误发生在

    var productInfo = products.Find<DALProduct>(p => p.ID.ToString().Equals(order.ProductID)).FirstOrDefault();
I define ID as GUID in model like below
    [BsonId]
    public Guid ID { get; set; }

它会抛出像"{document}{_id}.ToString() is not supported."这样的异常 如何避免这种情况

【问题讨论】:

标签: c# mongodb transactions mongodb-.net-driver


【解决方案1】:

我可以看到它执行了 'session.AbortTransaction();',但数据仍然被插入。

执行操作的原因(即中止后仍插入数据),因为操作不包含在事务会话中。

所有的 CRUD 操作都应该有一个重载方法,将 IClientSessionHandle 指定为其第一个参数。例如:

Task InsertOneAsync(IClientSessionHandle session, TDocument document, InsertOneOptions options = null, CancellationToken cancellationToken = default(CancellationToken));

请参阅:MongoDB .NET/C# 驱动程序 v2.8.1 中的 InsertOneAsyncReplaceOneAsync

为确保操作包含在事务会话中,请将会话作为参数传递给 CRUD 操作。任何没有会话对象的操作都将在会话之外执行。

【讨论】:

    猜你喜欢
    • 2019-05-28
    • 2019-09-18
    • 1970-01-01
    • 2019-01-27
    • 1970-01-01
    • 1970-01-01
    • 2012-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多