Esempio n. 1
0
        public void Commit()
        {
            if (Flags != (TransactionFlags.ReadWrite))
            {
                return;                 // nothing to do
            }
            if (Committed)
            {
                throw new InvalidOperationException("Cannot commit already commited transaction.");
            }

            if (RolledBack)
            {
                throw new InvalidOperationException("Cannot commit rolledback transaction.");
            }

            FlushAllMultiValues();

            State.Root.State.InWriteTransaction          = false;
            State.FreeSpaceRoot.State.InWriteTransaction = false;

            foreach (var tree in Trees)
            {
                tree.State.InWriteTransaction = false;
                var treeState = tree.State;
                if (treeState.IsModified)
                {
                    var treePtr = (TreeRootHeader *)State.Root.DirectAdd(this, tree.Name, sizeof(TreeRootHeader));
                    treeState.CopyTo(treePtr);
                }
            }

#if DEBUG
            if (State.Root != null && State.FreeSpaceRoot != null)
            {
                Debug.Assert(State.Root.State.RootPageNumber != State.FreeSpaceRoot.State.RootPageNumber);
            }
#endif

            _txHeader->LastPageNumber    = _state.NextPageNumber - 1;
            _txHeader->PageCount         = _allocatedPagesInTransaction;
            _txHeader->OverflowPageCount = _overflowPagesInTransaction;
            _state.Root.State.CopyTo(&_txHeader->Root);
            _state.FreeSpaceRoot.State.CopyTo(&_txHeader->FreeSpace);

            _txHeader->TxMarker |= TransactionMarker.Commit;

            if (_allocatedPagesInTransaction + _overflowPagesInTransaction > 0)             // nothing changed in this transaction
            {
                _journal.WriteToJournal(this, _allocatedPagesInTransaction + _overflowPagesInTransaction + PagesTakenByHeader);
                FlushedToJournal = true;
            }

            Committed = true;
            AfterCommit(this);
        }
Esempio n. 2
0
        private void CommitStage2_WriteToJournal()
        {
            // In the case of non-lazy transactions, we must flush the data from older lazy transactions
            // to ensure the sequentiality of the data.
            var numberOfWrittenPages = _journal.WriteToJournal(this);

            FlushedToJournal = true;

            if (_requestedCommitStats != null)
            {
                _requestedCommitStats.NumberOfModifiedPages     = numberOfWrittenPages.NumberOfUncompressedPages;
                _requestedCommitStats.NumberOf4KbsWrittenToDisk = numberOfWrittenPages.NumberOf4Kbs;
            }
        }
Esempio n. 3
0
        private void CommitStage2_WriteToJournal()
        {
            // In the case of non-lazy transactions, we must flush the data from older lazy transactions
            // to ensure the sequentiality of the data.
            Stopwatch sp = null;

            if (_requestedCommitStats != null)
            {
                sp = Stopwatch.StartNew();
            }
            var numberOfWrittenPages = _journal.WriteToJournal(this, out var journalFilePath);

            FlushedToJournal = true;

            if (_requestedCommitStats != null)
            {
                _requestedCommitStats.WriteToJournalDuration    = sp.Elapsed;
                _requestedCommitStats.NumberOfModifiedPages     = numberOfWrittenPages.NumberOfUncompressedPages;
                _requestedCommitStats.NumberOf4KbsWrittenToDisk = numberOfWrittenPages.NumberOf4Kbs;
                _requestedCommitStats.JournalFilePath           = journalFilePath;
            }
        }
Esempio n. 4
0
        private void CommitStage2_WriteToJournal()
        {
            // In the case of non-lazy transactions, we must flush the data from older lazy transactions
            // to ensure the sequentiality of the data.
            Stopwatch sp = null;

            if (_requestedCommitStats != null)
            {
                sp = Stopwatch.StartNew();
            }

            string journalFilePath;
            CompressedPagesResult numberOfWrittenPages;

            try
            {
                numberOfWrittenPages = _journal.WriteToJournal(this, out journalFilePath);
                FlushedToJournal     = true;
                _updatePageTranslationTableAndUnusedPages = numberOfWrittenPages.UpdatePageTranslationTableAndUnusedPages;
                if (SimulateThrowingOnCommitStage2)
                {
                    ThrowSimulateErrorOnCommitStage2();
                }
            }
            catch
            {
                _disposed |= TxState.Errored;
                throw;
            }

            if (_requestedCommitStats != null)
            {
                _requestedCommitStats.WriteToJournalDuration    = sp.Elapsed;
                _requestedCommitStats.NumberOfModifiedPages     = numberOfWrittenPages.NumberOfUncompressedPages;
                _requestedCommitStats.NumberOf4KbsWrittenToDisk = numberOfWrittenPages.NumberOf4Kbs;
                _requestedCommitStats.JournalFilePath           = journalFilePath;
            }
        }
Esempio n. 5
0
        public void Commit()
        {
            if (Flags != (TransactionFlags.ReadWrite))
            {
                return;                 // nothing to do
            }
            if (Committed)
            {
                throw new InvalidOperationException("Cannot commit already committed transaction.");
            }

            if (RolledBack)
            {
                throw new InvalidOperationException("Cannot commit rolled-back transaction.");
            }

            FlushAllMultiValues();

            State.Root.State.InWriteTransaction          = false;
            State.FreeSpaceRoot.State.InWriteTransaction = false;

            foreach (var tree in Trees)
            {
                if (tree == null)
                {
                    continue;
                }
                tree.State.InWriteTransaction = false;
                var treeState = tree.State;
                if (treeState.IsModified)
                {
                    var treePtr = (TreeRootHeader *)State.Root.DirectAdd((Slice)tree.Name, sizeof(TreeRootHeader));
                    treeState.CopyTo(treePtr);
                }
            }

#if DEBUG
            if (State.Root != null && State.FreeSpaceRoot != null)
            {
                Debug.Assert(State.Root.State.RootPageNumber != State.FreeSpaceRoot.State.RootPageNumber);
            }
#endif

            _txHeader->LastPageNumber    = _state.NextPageNumber - 1;
            _txHeader->PageCount         = _allocatedPagesInTransaction;
            _txHeader->OverflowPageCount = _overflowPagesInTransaction;
            _state.Root.State.CopyTo(&_txHeader->Root);
            _state.FreeSpaceRoot.State.CopyTo(&_txHeader->FreeSpace);

            _txHeader->TxMarker |= TransactionMarker.Commit;

            if (_allocatedPagesInTransaction + _overflowPagesInTransaction > 0)             // nothing changed in this transaction
            {
                _journal.WriteToJournal(this, _allocatedPagesInTransaction + _overflowPagesInTransaction + PagesTakenByHeader);
                FlushedToJournal = true;
            }

            // release scratch file page allocated for the transaction header
            _env.ScratchBufferPool.Free(_transactionHeaderPage.ScratchFileNumber, _transactionHeaderPage.PositionInScratchBuffer, -1);

            Committed = true;
            AfterCommit(this);

            if (Environment.IsDebugRecording)
            {
                RecordTransactionState(this, DebugActionType.TransactionCommit);
            }
        }
Esempio n. 6
0
        public void Commit()
        {
            if (_disposed)
            {
                throw new ObjectDisposedException("Transaction");
            }

            if (Flags != (TransactionFlags.ReadWrite))
            {
                return; // nothing to do
            }
            if (Committed)
            {
                throw new InvalidOperationException("Cannot commit already committed transaction.");
            }

            if (RolledBack)
            {
                throw new InvalidOperationException("Cannot commit rolled-back transaction.");
            }

            while (_pagesToFreeOnCommit.Count > 0)
            {
                FreePage(_pagesToFreeOnCommit.Pop());
            }
            _txHeader->LastPageNumber = _state.NextPageNumber - 1;
            _state.Root.CopyTo(&_txHeader->Root);

            _txHeader->TxMarker |= TransactionMarker.Commit;

            var totalNumberOfAllocatedPages = _allocatedPagesInTransaction + _overflowPagesInTransaction;

            if (totalNumberOfAllocatedPages > 0 || // nothing changed in this transaction
                                                   // allow call to writeToJournal for flushing lazy tx
                (IsLazyTransaction == false && _journal?.HasDataInLazyTxBuffer() == true))
            {
                // In the case of non-lazy transactions, we must flush the data from older lazy transactions
                // to ensure the sequentiality of the data.
                var numberOfWrittenPages = _journal.WriteToJournal(this, totalNumberOfAllocatedPages + PagesTakenByHeader);
                FlushedToJournal = true;

                if (_requestedCommitStats != null)
                {
                    _requestedCommitStats.NumberOfModifiedPages      = totalNumberOfAllocatedPages + PagesTakenByHeader;
                    _requestedCommitStats.NumberOfPagesWrittenToDisk = numberOfWrittenPages;
                }
            }

            // an exception being throw after the transaction has been committed to disk
            // will corrupt the in memory state, and require us to restart (and recover) to
            // be in a valid state
            try
            {
                ValidateAllPages();

                // release scratch file page allocated for the transaction header
                _env.ScratchBufferPool.Free(_transactionHeaderPage.ScratchFileNumber, _transactionHeaderPage.PositionInScratchBuffer, null);

                Committed = true;
                _env.TransactionAfterCommit(this);
            }
            catch (Exception e)
            {
                _env.CatastrophicFailure = ExceptionDispatchInfo.Capture(e);

                throw;
            }
            OnCommit?.Invoke(this);
        }