Пример #1
0
        /// <summary>
        /// Rolls back the current transaction.
        /// </summary>
        /// <exception cref="TransactionException">Thrown if the stack is empty.</exception>
        internal void Rollback()
        {
            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 rollback BASE", "ID=" + id.ToString());
                }
                else
                {
                    manager.Trace(0, string.Format("Begin rollback NESTED [{0}]", base.Count), "ID=" + id.ToString());
                }

                // Submit the operations being undone back to the
                // resource in the reverse order that they were
                // originally performed.

                ITransactedResource resource = manager.Resource;
                UpdateContext       context  = new UpdateContext(manager, false, false, true, ID);
                List <ILogPosition> positions;

                positions = operationLog.GetPositionsTo(transaction.Position);

                if (resource.BeginUndo(context))
                {
                    for (int i = 0; i < positions.Count; i++)
                    {
                        var operation = operationLog.Read(manager.Resource, positions[i]);

                        manager.Trace(0, "Undo: " + operation.Description, "ID=" + id.ToString());
                        resource.Undo(context, operation);
                    }
                }

                resource.EndUndo(context);

                if (base.Count == 0)
                {
                    manager.EndTransaction(this);
                    manager.Trace(0, "End rollback BASE", "ID=" + id.ToString());
                }
                else
                {
                    operationLog.Truncate(transaction.Position);
                    manager.Trace(0, string.Format("End rollback NESTED [{0}]", base.Count), "ID=" + id.ToString());
                }
            }
        }