本文介绍了使用mongodb 4.08社区服务器的c#中,多个文档事务不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need update multiple documents using mongodb transaction, mongodb community server version is 4.08, and mongodb driver for .net is 2.9 beta(also tried 2.8). From debugging, I can see it executed 'session.AbortTransaction();', but data was still inserted.

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;
}

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

Expect inserted order data can be rollback, actual result is the data has been inserted into db.

顺便说一句,错误发生在

BTW, the error occurs at

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

it will throw exception like "{document}{_id}.ToString() is not supported."How to avoid this

推荐答案

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

The reason why the operations are executed (i.e. data was still inserted after abort), because the operations are not contained within a transactional session.

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

All of the CRUD operations should have an overloaded methods that specifies IClientSessionHandle as its first argument. For example:

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

请参阅: InsertOneAsync ReplaceOneAsync .

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

To ensure the operations are contained within the transactional session, pass the session as an argument to the CRUD operations. Any operations that don't have the session object, will be executed outside of the session.

这篇关于使用mongodb 4.08社区服务器的c#中,多个文档事务不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 02:33