/// <summary> /// Performs a best efforts recovery of orphaned transactions. /// </summary> private void Recover() { var orphans = log.GetOrphanTransactions(); var context = new UpdateContext(this, true, false, false, Guid.Empty); IOperation operation; SysLog.LogWarning("Recovering [{0}] transactions for [{1}].", orphans.Count, resource.Name); Trace(0, "Begin Recovery", null); resource.BeginRecovery(context); for (int i = 0; i < orphans.Count; i++) { IOperationLog opLog = log.OpenOperationLog(orphans[i]); context.TransactionID = opLog.TransactionID; if (opLog.Mode == OperationLogMode.Redo) { if (resource.BeginRedo(context)) { foreach (ILogPosition pos in opLog.GetPositions(false)) { operation = opLog.Read(resource, pos); Trace(0, "Redo: " + operation.Description, "ID=" + context.TransactionID.ToString()); resource.Redo(context, operation); } } resource.EndRedo(context); } else { if (resource.BeginUndo(context)) { foreach (ILogPosition pos in opLog.GetPositions(true)) { operation = opLog.Read(resource, pos); Trace(0, "Undo: " + operation.Description, "ID=" + context.TransactionID.ToString()); resource.Undo(context, opLog.Read(resource, pos)); } } resource.EndUndo(context); } log.CloseOperationLog(opLog); } context.TransactionID = Guid.Empty; resource.EndRecovery(context); Trace(0, "End Recovery", null); }
/// <summary> /// Commits the current transaction. If this is the base transaction then /// the operation will be commited to the <see cref="ITransactedResource" />. /// </summary> /// <exception cref="TransactionException">Thrown if the stack is empty.</exception> internal void Commit() { Transaction transaction; using (TimedLock.Lock(syncLock)) { if (base.Count == 0) { throw new TransactionException(EmptyMsg); } transaction = base.Pop(); if (base.Count == 0) { manager.Trace(0, "Begin commit BASE", "ID=" + id.ToString()); // We're committing the base transaction so play the redo log // to the resource and then delete the log when we're finished. ITransactedResource resource = manager.Resource; UpdateContext context = new UpdateContext(manager, false, true, false, ID); List <ILogPosition> positions; positions = operationLog.GetPositions(false); if (resource.BeginRedo(context)) { for (int i = 0; i < positions.Count; i++) { var operation = operationLog.Read(manager.Resource, positions[i]); manager.Trace(0, "Redo: " + operation.Description, "ID=" + id.ToString()); resource.Redo(context, operation); } } resource.EndRedo(context); manager.EndTransaction(this); manager.Trace(0, "End commit BASE", "ID=" + id.ToString()); } else { manager.Trace(0, string.Format("Commit NESTED [{0}]", base.Count), "ID=" + id.ToString()); } } }
// GET api/operations public IEnumerable <Operation> Get(int position, int count) { CheckState(); return(operationLog.Read(position, count)); }