示例#1
0
        private void CommitStage3_DisposeTransactionResources()
        {
            // an exception being thrown 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();

                Allocator.Release(ref _txHeaderMemory);

                Committed = true;
                _env.TransactionAfterCommit(this);

                if (_asyncCommitNextTransaction != null)
                {
                    var old = _asyncCommitNextTransaction.JournalFiles;
                    _asyncCommitNextTransaction.JournalFiles = _env.Journal.Files;
                    foreach (var journalFile in _asyncCommitNextTransaction.JournalFiles)
                    {
                        journalFile.AddRef();
                    }
                    foreach (var journalFile in old)
                    {
                        journalFile.Release();
                    }
                }
            }
            catch (Exception e)
            {
                _env.Options.SetCatastrophicFailure(ExceptionDispatchInfo.Capture(e));

                throw;
            }
        }
示例#2
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);
        }