多文档事务在使用 mongodb 4.08 社区服务器的 C# 中不起作用

2024-05-30

我需要使用 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;
}

期望插入的订单数据可以回滚,实际结果是数据已经插入到数据库中。

顺便说一句,错误发生在

    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."如何避免这种情况


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

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

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

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

See: InsertOne异步 https://github.com/mongodb/mongo-csharp-driver/blob/v2.8.1/src/MongoDB.Driver/IMongoCollection.cs#L759 and ReplaceOne异步 https://github.com/mongodb/mongo-csharp-driver/blob/v2.8.1/src/MongoDB.Driver/IMongoCollection.cs#L907在 MongoDB .NET/C# 驱动程序 v2.8.1 中。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多文档事务在使用 mongodb 4.08 社区服务器的 C# 中不起作用 的相关文章

随机推荐