When I do a POST to a controller, I intermittently get threading errors - though a lot of the time everything will work perfectly. These are the most common two:
New transaction is not allowed because there are other threads running in the session.
The transaction operation cannot be performed because there are pending requests working on this transaction.
I have read multiple replies on why this happens. Such as this one and this one, but I can't say I understand. I know just posting code is horrible practice on SO, and I generally do my best to avoid it, but I really don't know what to ask past "Can you please take a look and let me know if you see any obvious problems."
// 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); } Note: I am 100% sure this has to do with async and is not MongoDb specific. The code below is equivalent of saving something to SQL with EF. I am sure the other Mongo bits are completely irrelevant to the question.
await mongoItems.FindOneAndUpdateAsync( Builders<BsonDocument>.Filter.Eq("_id", item.Id), update); db is our Entity Framework dbContext (just normal dbContext used with SQL, we have two databases - Mongo and SQL).