/// <summary> /// 返回上一步操作 /// </summary> /// <typeparam name="T">需要接受的数据对象类型</typeparam> /// <param name="refadd">需要接受的数据对象引用</param> public void Previous <T>(out T refadd) where T : class, new() { Transaction tran = _tranStack.Pop(); if (tran == null)//顶层事务 { Transaction.Current.Rollback(); } // tran.Rollback();//回滚本事务,将触发所有克隆事务的回滚。 if (PreviousEvent != null) { if (PreviousEvent.GetInvocationList().Length > 0) { //设置上一步数据对象 refadd = (_resourceStack.Pop() as IReversibleGetResourceData <T>).GetPreviousData(); PreviousEvent(Transaction.Current); return; } } refadd = new T();//事务处理异常 }
void InitializeFromPrimary() { atomsFields = new ByteAtomTable(); atomsRecords = new ByteAtomTable(); atomsProcesses = new ByteAtomTable(); listEventFields = new List <List <int> >(); byte[] byRecordEscape = ByteWindow.MakeBytes("$R"); idRecordEscape = atomsFields.EnsureContains(byRecordEscape); byte[] byTimeEscape = ByteWindow.MakeBytes("$T"); idTimeEscape = atomsFields.EnsureContains(byTimeEscape); byte[] byTimeOffsetEscape = ByteWindow.MakeBytes("$TimeOffset"); idTimeOffsetEscape = atomsFields.EnsureContains(byTimeOffsetEscape); byte[] byWhenEscape = ByteWindow.MakeBytes("$When"); idWhenEscape = atomsFields.EnsureContains(byWhenEscape); byte[] byFirstEscape = ByteWindow.MakeBytes("$First"); idFirstEscape = atomsFields.EnsureContains(byFirstEscape); byte[] byLastEscape = ByteWindow.MakeBytes("$Last"); idLastEscape = atomsFields.EnsureContains(byLastEscape); byte[] byBeginHeader = ByteWindow.MakeBytes("BeginHeader"); byte[] byEndHeader = ByteWindow.MakeBytes("EndHeader"); ByteWindow b = new ByteWindow(); threads.Clear(); offsets.Clear(); while (stm.ReadLine(b)) { if (b.StartsWith(byBeginHeader)) { break; } } while (stm.ReadLine(b)) { if (b.StartsWith(byEndHeader)) { break; } b.Field(0).Trim(); int iCountBefore = atomsRecords.Count; atomsRecords.EnsureContains(b); if (atomsRecords.Count == iCountBefore) { continue; } List <int> listFields = new List <int>(); listEventFields.Add(listFields); listFields.Add(0); // the ID for $R, the record escape field // start from field 1 -- that skips only field 0 which is already mapped to $R for (int i = 1; i < b.fieldsLen; i++) { b.Field(i).Trim(); int id = atomsFields.EnsureContains(b); listFields.Add(id); } } stackIgnoreEvents = new bool[atomsRecords.Count]; foreach (string strEvent in stackIgnoreEventStrings) { int id = atomsRecords.Lookup(strEvent); if (id >= 0) { stackIgnoreEvents[id] = true; } } recordInfo = new RecordInfo[atomsRecords.Count]; int idThreadField = atomsFields.Lookup("ThreadID"); int idFileNameField = atomsFields.Lookup("FileName"); int idTypeField = atomsFields.Lookup("Type"); int idSizeField = atomsFields.Lookup("Size"); int idIOSizeField = atomsFields.Lookup("IOSize"); int idElapsedTimeField = atomsFields.Lookup("ElapsedTime"); for (int i = 0; i < recordInfo.Length; i++) { List <int> fieldList = listEventFields[i]; recordInfo[i].threadField = fieldList.IndexOf(idThreadField); recordInfo[i].sizeField = fieldList.IndexOf(idSizeField); if (-1 == recordInfo[i].sizeField) { recordInfo[i].sizeField = fieldList.IndexOf(idIOSizeField); } recordInfo[i].goodNameField = fieldList.IndexOf(idFileNameField); if (-1 == recordInfo[i].goodNameField) { recordInfo[i].goodNameField = fieldList.IndexOf(idTypeField); } recordInfo[i].elapsedTimeField = fieldList.IndexOf(idElapsedTimeField); } int idT_DCEnd = atomsRecords.Lookup("T-DCEnd"); int idT_DCStart = atomsRecords.Lookup("T-DCStart"); int idT_Start = atomsRecords.Lookup("T-Start"); int idT_End = atomsRecords.Lookup("T-End"); int idCSwitch = atomsRecords.Lookup("CSwitch"); int idStack = atomsRecords.Lookup("Stack"); int idAlloc = atomsRecords.Lookup("Allocation"); int idFirstReliableEventTimeStamp = atomsRecords.Lookup("FirstReliableEventTimeStamp"); int idFirstReliableCSwitchEventTimeStamp = atomsRecords.Lookup("FirstReliableCSwitchEventTimeStamp"); long tNext = 100000; long t = 0; // seed offsets for the 0th record offsets.Add(stm.Position); listInitialTime = new List <TimeMark>(); maxCPU = 64; CPUState[] state = new CPUState[maxCPU]; const int maxEvent = 16; PreviousEvent[] prev = new PreviousEvent[maxEvent]; int iNextEvent = 0; stackTypes = new bool[atomsRecords.Count]; Dictionary <int, int> dictStartedThreads = new Dictionary <int, int>(); ByteWindow record = new ByteWindow(); ByteWindow bThreadProc = new ByteWindow(); ByteWindow bProcess = new ByteWindow(); // the first line of the trace is the trace info, that, importantly, has the OSVersion tag if (stm.ReadLine(b)) { traceinfo = b.GetString(); } else { traceinfo = "None"; } while (stm.ReadLine(b)) { if (b.len < typeLen) { continue; } record.Assign(b, 0).Trim(); int idrec = atomsRecords.Lookup(record); if (idrec < 0) { continue; } if (idrec == idFirstReliableCSwitchEventTimeStamp || idrec == idFirstReliableEventTimeStamp) { continue; } recordInfo[idrec].count++; t = b.GetLong(1); while (t >= tNext) { tNext = AddTimeRow(tNext, state); } if (idrec != idStack && !stackIgnoreEvents[idrec]) { prev[iNextEvent].time = t; prev[iNextEvent].eventId = idrec; iNextEvent = (iNextEvent + 1) % maxEvent; } if (idrec == idStack) { int i = iNextEvent; for (; ;) { if (--i < 0) { i = maxEvent - 1; } if (i == iNextEvent) { break; } if (prev[i].time == t) { stackTypes[prev[i].eventId] = true; break; } } } else if (idrec == idT_Start || idrec == idT_End || idrec == idT_DCStart || idrec == idT_DCEnd) { ThreadInfo ti = new ThreadInfo(); ti.threadid = b.GetInt(fldTStartThreadId); bool fStarted = dictStartedThreads.ContainsKey(ti.threadid); if (idrec == idT_Start) { ti.timestamp = t; } else if (idrec == idT_DCStart) { ti.timestamp = 0; } else { if (fStarted) { continue; } ti.timestamp = 0; } if (!fStarted) { dictStartedThreads.Add(ti.threadid, 0); } bThreadProc.Assign(b, fldTStartThreadProc).Trim(); bProcess.Assign(b, fldTStartProcess).Trim(); ti.processPid = bProcess.Clone(); if (atomsProcesses.Lookup(bProcess) == -1) { atomsProcesses.EnsureContains(ti.processPid); ProcessInfo pi = new ProcessInfo(); pi.processPid = ti.processPid; processes.Add(pi); } bProcess.Truncate((byte)'(').Trim(); ti.processNopid = bProcess.Clone(); ti.threadproc = bThreadProc.Clone(); threads.Add(ti); } else if (idrec == idCSwitch) { int newTid = b.GetInt(fldCSwitchNewTID); int oldTid = b.GetInt(fldCSwitchOldTID); int cpu = b.GetInt(fldCSwitchCPU); if (cpu < 0 || cpu > state.Length) { continue; } int tusage = (int)(t - state[cpu].time); if (state[cpu].tid != 0 && tusage > 0) { state[cpu].usage += tusage; } state[cpu].time = t; state[cpu].tid = newTid; state[cpu].active = true; } } AddTimeRow(t, state); threads.Sort(); int tid = -1; mp_tid_firstindex = new Dictionary <int, int>(); for (int i = 0; i < threads.Count; i++) { if (tid != threads[i].threadid) { tid = threads[i].threadid; mp_tid_firstindex.Add(tid, i); } } sortedThreads = new int[threads.Count]; for (int i = 0; i < sortedThreads.Length; i++) { sortedThreads[i] = i; } Array.Sort(sortedThreads, delegate(int id1, int id2) { byte[] b1 = threads[id1].processPid; byte[] b2 = threads[id2].processPid; int cmp = ByteWindow.CompareBytes(b1, b2, true); if (cmp != 0) { return(cmp); } if (threads[id1].threadid < threads[id2].threadid) { return(-1); } if (threads[id1].threadid > threads[id2].threadid) { return(1); } return(0); } ); sortedProcesses = new int[processes.Count]; for (int i = 0; i < sortedProcesses.Length; i++) { sortedProcesses[i] = i; } Array.Sort(sortedProcesses, delegate(int id1, int id2) { byte[] b1 = processes[id1].processPid; byte[] b2 = processes[id2].processPid; return(ByteWindow.CompareBytes(b1, b2, true)); } ); tmax = t; TrySaveState(); }