public BookOrderStats GetBookOrderStats(IEntitySession session, Guid orderId) { try { var order = session.GetEntity<IBookOrder>(orderId, LockOptions.SharedRead); return new BookOrderStats() { OrderId = orderId, LineCount = order.Lines.Count, MaxPrice = order.Lines.Max(ol => ol.Price) }; } finally { session.ReleaseLocks(); } }
public BookOrderStats GetBookOrderStats(IEntitySession session, Guid orderId) { try { var order = session.GetEntity <IBookOrder>(orderId, LockOptions.SharedRead); return(new BookOrderStats() { OrderId = orderId, LineCount = order.Lines.Count, MaxPrice = order.Lines.Max(ol => ol.Price) }); } finally { session.ReleaseLocks(); } }
private void RunRandomReadWriteOp(Guid[] docIds, LockType readLock, LockType writeLock, int readWriteCount) { var rand = new Random(Thread.CurrentThread.ManagedThreadId); IEntitySession session = null; // Use context with its own buffered op log - all entries related to single load/update operation are buffered, // and then flushed together at the end of loop body; so they will appear together in the output file var ctx = new OperationContext(_app); ctx.Log = new BufferedLog(ctx.LogContext); for (int i = 0; i < readWriteCount; i++) { session = ctx.OpenSession(); var randomDocId = docIds[rand.Next(docIds.Length)]; IDoc iDoc; IDocDetail iDet; int randomOp = -1; try { Thread.Yield(); var randomValueName = "N" + rand.Next(5); randomOp = rand.Next(7); switch (randomOp) { case 0: case 1: //read and check total session.LogMessage("\r\n----------------- Load, check Doc total ---------------------"); iDoc = session.GetEntity <IDoc>(randomDocId, readLock); Thread.Yield(); //to let other thread mess it up var valuesSum = iDoc.Details.Sum(v => v.Value); if (valuesSum != iDoc.Total) { session.LogMessage("!!!! Sum error: Doc.Total: {0}, Sum(Value): {1}", iDoc.Total, valuesSum); Interlocked.Increment(ref _sumErrorCount); } Thread.Yield(); session.ReleaseLocks(); session.LogMessage("\r\n-------------- Completed Load/check total ---------------------"); break; case 2: case 3: case 4: //insert/update, we give it an edge over deletes, to have 2 upserts for 1 delete session.LogMessage("\r\n----------------- Update/insert DocDetail ---------------------"); iDoc = session.GetEntity <IDoc>(randomDocId, writeLock); Thread.Yield(); iDet = iDoc.Details.FirstOrDefault(iv => iv.Name == randomValueName); if (iDet == null) { iDet = session.NewEntity <IDocDetail>(); iDet.Doc = iDoc; iDet.Name = randomValueName; iDoc.Details.Add(iDet); //to correctly calculate total } iDet.Value = rand.Next(10); iDoc.Total = iDoc.Details.Sum(v => v.Value); Thread.Yield(); session.SaveChanges(); session.LogMessage("\r\n------Completed Update/insert doc detail ---------------------"); var entSession = (Vita.Entities.Runtime.EntitySession)session; if (entSession.CurrentConnection != null) { Debugger.Break(); //check that connection is closed and removed from session } break; case 6: //delete if exists session.LogMessage("\r\n----------------- Delete doc detail ---------------------"); //Note: deletes do not throw any errors - if record does not exist (had been just deleted), stored proc do not throw error iDoc = session.GetEntity <IDoc>(randomDocId, writeLock); Thread.Yield(); //allow others mess up iDet = iDoc.Details.FirstOrDefault(iv => iv.Name == randomValueName); if (iDet != null) { session.DeleteEntity(iDet); iDoc.Details.Remove(iDet); iDoc.Total = iDoc.Details.Sum(v => v.Value); session.SaveChanges(); // even if there's no changes, it will release lock } else { session.ReleaseLocks(); } session.LogMessage("\r\n----------------- Completed delete doc detail ---------------------"); break; }//switch } catch (Exception ex) { //most will be UniqueIndexViolation Debug.WriteLine(ex.ToLogString()); System.Threading.Interlocked.Increment(ref _updateErrorCount); session.Context.Log.AddEntry(new ErrorLogEntry(ctx.LogContext, ex)); var entSession = (Vita.Entities.Runtime.EntitySession)session; if (entSession.CurrentConnection != null) { entSession.CurrentConnection.Close(); } //session.Context.Log.Flush(); _app.Flush(); } finally { //_app.Flush(); } //session.Context.Log.Flush(); } //for i } //method
private void RunRandomReadWriteOp(Guid[] docIds, LockOptions readOptions, LockOptions writeOptions, int readWriteCount) { var rand = new Random(Thread.CurrentThread.ManagedThreadId); IEntitySession session = null; for (int i = 0; i < readWriteCount; i++) { var randomDocId = docIds[rand.Next(docIds.Length)]; var randomValueName = "N" + rand.Next(5); IDoc iDoc; IDocDetail iDet; int randomOp = -1; try { Thread.Yield(); session = _app.OpenSession(); randomOp = rand.Next(5); switch (randomOp) { case 0: case 1: //insert/update, we give it an edge over deletes, to have 2 upserts for 1 delete session.LogMessage("\r\n----------------- Update/insert value ---------------------"); iDoc = session.GetEntity <IDoc>(randomDocId, writeOptions); Thread.Yield(); iDet = iDoc.Details.FirstOrDefault(iv => iv.Name == randomValueName); if (iDet == null) { iDet = session.NewEntity <IDocDetail>(); iDet.Doc = iDoc; iDet.Name = randomValueName; iDoc.Details.Add(iDet); //to correctly calculate total } iDet.Value = rand.Next(10); iDoc.Total = iDoc.Details.Sum(v => v.Value); Thread.Yield(); session.SaveChanges(); var entSession = (Vita.Entities.Runtime.EntitySession)session; if (entSession.CurrentConnection != null) { Debugger.Break(); //check that connection is closed and removed from session } break; case 2: //delete if exists session.LogMessage("\r\n----------------- Delete value ---------------------"); //Note: deletes do not throw any errors - if record does not exist (had been just deleted), stored proc do not throw error iDoc = session.GetEntity <IDoc>(randomDocId, writeOptions); Thread.Yield(); //allow others mess up iDet = iDoc.Details.FirstOrDefault(iv => iv.Name == randomValueName); if (iDet != null) { session.DeleteEntity(iDet); iDoc.Details.Remove(iDet); iDoc.Total = iDoc.Details.Sum(v => v.Value); } Thread.Yield(); session.SaveChanges(); // even if there's no changes, it will release lock break; case 3: case 4: //read and check total session.LogMessage("\r\n----------------- Loading doc ---------------------"); iDoc = session.GetEntity <IDoc>(randomDocId, readOptions); Thread.Yield(); //to let other thread mess it up var valuesSum = iDoc.Details.Sum(v => v.Value); if (valuesSum != iDoc.Total) { session.LogMessage("!!!! Sum error: Doc.Total: {0}, Sum(Value): {1}", iDoc.Total, valuesSum); Interlocked.Increment(ref _sumErrorCount); } Thread.Yield(); session.ReleaseLocks(); break; }//switch WriteLog(session); } catch (Exception ex) { //most will be UniqueIndexViolation Debug.WriteLine(ex.ToLogString()); System.Threading.Interlocked.Increment(ref _updateErrorCount); if (session != null) { WriteLog(session); var log = session.Context.LocalLog.GetAllAsText(); Debug.WriteLine(log); var entSession = (Vita.Entities.Runtime.EntitySession)session; if (entSession.CurrentConnection != null) { entSession.CurrentConnection.Close(); } } } } //for i } //method