实体框架事务期间与线程相关的多个错误

本文关键字:错误 线程 事务 框架 实体 | 更新日期: 2023-09-27 18:06:22

当我对控制器进行POST时,我间歇性地得到线程错误-尽管很多时候一切都将完美地工作。这是最常见的两种:

不允许新事务,因为会话中有其他线程正在运行。

事务操作无法执行,因为有挂起的请求正在处理此事务。

我读了很多关于为什么会发生这种情况的回复。比如这个和这个,但我不能说我理解。我知道仅仅在SO上发布代码是一种可怕的做法,我通常会尽我所能避免它,但我真的不知道该问过去什么;"你能看看吗?如果你看到任何明显的问题,请告诉我。"

// POST: api/CheckOuts
[AccessType(AccessType.Create)]
[HttpPost, Route("")]
[ResponseType(typeof(CheckOut))]
public async Task<IHttpActionResult> PostCheckOut(TransactionViewModel<CheckOut> tx)
{
    //check if tx is a valid CheckOut Model Object
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }
    tx.Transaction.OrganizationId = SelectedOrganizationID;
    tx.Transaction.OfficeId = SelectedOfficeID;
    tx.Transaction.CheckedOutById = UserId;
    tx.Transaction.Date = DateTime.UtcNow;
    var items = tx.Transaction.Items.ToList();
    long checkedOutStatus =  db.Statuses.First( a => a.Name == "Checked Out" ).Id;
    long checkedInStatus =  db.Statuses.First( a => a.Name == "Checked In" ).Id;  
    //check item status
    if( !items.TrueForAll( i=> i.StatusId == checkedInStatus ) )
    {
        return BadRequest("Not all items are in 'Checked In' state.");
    }
    var mongoItems = GetMongoCollection<BsonDocument>(MongoConstants.ItemsCollection);
    items.ForEach(async item =>
    {
        var builder = Builders<BsonDocument>.Update;
        var update = builder.Set("StatusId", checkedOutStatus)
            .Set("CustodianId", tx.Transaction.TakenById)
            .Set<BsonDocument, int?>("LocationId", null)
            .Set<BsonDocument, string>("Location", null);
        await mongoItems.FindOneAndUpdateAsync(
        Builders<BsonDocument>.Filter.Eq("_id", item.Id),
                update);
        await AddItemHistory(item, UserId);
        var primaryKeyOfTheItemId = db.ItemIds.Single(i => i.Item_Id == item.Id);
        tx.Transaction.ItemIds.Add(primaryKeyOfTheItemId);
    });
        //add item
    db.CheckOuts.Add(tx.Transaction);
       
    await db.SaveChangesAsync(UserId);
    return CreatedAtRoute("DefaultApi", new {controller = "checkouts", id = tx.Transaction.Id }, tx.Transaction);
}

注意:我100%肯定这与async有关,而不是MongoDb特定的。下面的代码相当于用EF将一些东西保存为SQL。我确信Mongo的其他部分与这个问题完全无关。

await mongoItems.FindOneAndUpdateAsync(
    Builders<BsonDocument>.Filter.Eq("_id", item.Id),
    update);

db是我们的实体框架dbContext(只是普通的dbContext与SQL一起使用,我们有两个数据库- Mongo和SQL)

实体框架事务期间与线程相关的多个错误

我没有看到你在方法体中创建上下文。实体框架上下文不是线程安全的。