Пример #1
0
        override internal protected void TrackModification(CollectionOnDisk collection, bool untrack = false)
        {
            CollectionOnDisk p   = collection; // Collection.GetTopParent();
            RecordKey        key = CreateKey(p);

            if (!untrack)
            {
                ModifiedCollections[key] = p;
                return;
            }
            ModifiedCollections.Remove(key);
        }
Пример #2
0
        /// <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);
                }
            }
        }