/// <summary> /// Commit this transaction /// </summary> /// <param name="phase"></param> /// <returns></returns> public override bool InternalCommit(CommitPhase phase) { //** don't do anything as if Commit reached this point, it should just be treated as succeeded. //** Remember, this is the Root transaction which Commit gets called only when inner trans succeeded. if (phase == CommitPhase.SecondPhase) { //** record completion of this transaction in log file CleanupLogger(); //GC.SuppressFinalize(this); } else if (CurrentCommitPhase == CommitPhase.UnCommitted) { if (Server != null) { //Server.Flush(); CurrentCommitPhase = CommitPhase.SecondPhase; Server.Transaction = null; } else { CurrentCommitPhase = CommitPhase.SecondPhase; } } return(true); }
/// <summary> /// Commit starting Children transaction(s) /// </summary> /// <param name="phase"></param> virtual public bool Commit(CommitPhase phase) { Flush(); if (Children != null && Children.Count > 0) { var childrenCopy = new ITransactionLogger[Children.Count]; Children.CopyTo(childrenCopy, 0); foreach (ITransactionLogger trans in childrenCopy) { if (!trans.InternalCommit(phase)) { return(false); } } } // all Transaction classes implement ITransactionLogger so this cast should be OK.. return(this.InternalCommit(phase)); }
/// <summary> /// Commit a transaction /// </summary> /// <param name="phase"> /// FirstPhase will make changes permanent but keep transaction log so rollback /// is still possible. /// /// SecondPhase will: /// 1. call FirstPhase commit if this transaction is in UnCommitted phase /// 2. clear the transaction log to complete Commit /// NOTE: Rollback is no longer allowed after completion of SecondPhase /// </param> ///<returns>true if successful otherwise false</returns> public override bool InternalCommit(CommitPhase phase) { if (CurrentCommitPhase == CommitPhase.Committed) { throw new InvalidOperationException(string.Format("Transaction '{0}' is already committed.", Id)); } _inCommit++; try { switch (phase) { case CommitPhase.FirstPhase: if (CurrentCommitPhase == CommitPhase.UnCommitted) { RollbackConflicts(); //** save all cached data of each collection var parents = new Dictionary <CollectionOnDisk, object>(ModifiedCollections.Count); var closeColls = new List <RecordKey>(); foreach (KeyValuePair <RecordKey, CollectionOnDisk> kvp in ModifiedCollections) { CollectionOnDisk collection = kvp.Value; CollectionOnDisk ct = collection.GetTopParent(); if (ct.IsOpen) { parents[ct] = null; } else { closeColls.Add(kvp.Key); } } foreach (CollectionOnDisk collection in parents.Keys) { if (!collection.IsOpen) { continue; } collection.Flush(); collection.OnCommit(); } foreach (RecordKey k in closeColls) { ModifiedCollections.Remove(k); } //File.DeletedCollections.Flush(); CurrentCommitPhase = CommitPhase.FirstPhase; //** don't clear transaction log so rollback is still possible return(true); } break; case CommitPhase.SecondPhase: if (CurrentCommitPhase == CommitPhase.UnCommitted) { if (!Commit(CommitPhase.FirstPhase)) { break; } } if (CurrentCommitPhase == CommitPhase.FirstPhase) { //** mark second phase completed as when it starts, no turning back... CurrentCommitPhase = CommitPhase.SecondPhase; //** preserve the recycled segment so on rollback it can be restored... foreach (CollectionOnDisk collection in ModifiedCollections.Values) { if (!collection.IsOpen) { continue; } collection.HeaderData.RecycledSegmentBeforeTransaction = collection.HeaderData.RecycledSegment; if (collection.HeaderData.RecycledSegmentBeforeTransaction != null) { collection.HeaderData.RecycledSegmentBeforeTransaction = (DeletedBlockInfo) collection.HeaderData.RecycledSegmentBeforeTransaction.Clone(); } } //** delete new (AddStore), updated (LogCollection) and //** file growth segments (FileGrowthStore) "log entries" ClearStores(true); //** todo: Record on Trans Log the FileSet Remove action + info needed for //** commit resume "on crash and restart" 11/9/08 File.Delete(Server.Path + DataBackupFilename); //** todo: remove from trans Log the FileSet Remove action... 11/09/08 return(true); } break; } //** auto roll back this transaction if commit failed above if (CurrentCommitPhase != CommitPhase.Rolledback && CurrentCommitPhase != CommitPhase.SecondPhase) { Rollback(); } return(false); } finally { _inCommit--; if (Parent == null) { CollectionOnDisk.transaction = null; } else { Parent.Children.Remove(this); } } }
public abstract bool InternalCommit(CommitPhase phase);
private static void SetCommitPhase(this UIElement visual, CommitPhase commitPhase) { visual.SetValue(CommitPhaseProperty, commitPhase); }
public override bool InternalCommit(CommitPhase phase) { CurrentCommitPhase = phase; return(true); }
public override bool Commit(CommitPhase phase) { CurrentCommitPhase = CommitPhase.Committed; return(true); }
public override bool InternalCommit(CommitPhase phase) { return(true); }