예제 #1
0
        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
예제 #2
0
        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