транзакция с несколькими документами не работает в c # с использованием сервера сообщества mongodb 4.08 - PullRequest
1 голос
/ 26 апреля 2019

Мне нужно обновить несколько документов, используя транзакцию mongodb, версия сервера сообщества mongodb - 4.08, а драйвер .ongong для .net - 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." Как этого избежать

1 Ответ

0 голосов
/ 13 июля 2019

Я вижу, как он выполнил 'session.AbortTransaction ();', но данные все еще были вставлены.

Причина, по которой выполняются операции (т.е. данные все еще были вставлены после прерывания), потому что операции не содержатся в транзакционном сеансе.

Все операции CRUD должны иметь перегруженные методы, которые указывают IClientSessionHandle в качестве первого аргумента. Например:

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

См .: InsertOneAsync и ReplaceOneAsync в драйвере MongoDB .NET / C # v2.8.1.

Чтобы убедиться, что операции содержатся в транзакционном сеансе, передайте сеанс в качестве аргумента операциям CRUD. Любые операции, которые не имеют объекта сеанса, будут выполняться вне сеанса.

...