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); }
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; } }
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; } }
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; } }
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); } }
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); }