/// <summary> /// Completes the async commit began previously. Must be called *within* the /// write lock, and must happen *before* the new transaction call its own commit /// method. /// </summary> public void EndAsyncCommit() { if (AsyncCommit == null) { ThrowInvalidAsyncEndWithoutBegin(); return;// never reached } try { AsyncCommit.Wait(); } catch (Exception e) { // an exception being thrown while / after / somewhere in the middle // of writing to the journal means that we don't know what the current // state of the journal is. We have to shut down and run recovery to // come to a known good state _env.Options.SetCatastrophicFailure(ExceptionDispatchInfo.Capture(e)); throw; } if (AsyncCommit.Result) { Environment.LastWorkTime = DateTime.UtcNow; } CommitStage3_DisposeTransactionResources(); BeforeCommitFinalization?.Invoke(this); }
public void Dispose() { if (_encryptionBuffers != null) // Encryption enabled { foreach (var buffer in _encryptionBuffers) { NativeMemory.Free4KbAlignedMemory(buffer.Pointer, buffer.Size, buffer.AllocatingThread); } BeforeCommitFinalization?.Invoke(this); } OnDispose?.Invoke(this); }
/// <summary> /// Completes the async commit began previously. Must be called *within* the /// write lock, and must happen *before* the new transaction call its own commit /// method. /// </summary> public void EndAsyncCommit() { if (AsyncCommit == null) { ThrowInvalidAsyncEndWithoutBegin(); return;// never reached } AsyncCommit.Wait(); Environment.LastWorkTime = DateTime.UtcNow; CommitStage3_DisposeTransactionResources(); BeforeCommitFinalization?.Invoke(this); }
public void Dispose() { if (_encryptionBuffers != null) // Encryption enabled { foreach (var buffer in _encryptionBuffers) { PlatformSpecific.NativeMemory.Free4KbAlignedMemory(buffer.Pointer, buffer.Size, buffer.AllocatingThread); } var cryptoPagerTransactionState = ((IPagerLevelTransactionState)this).CryptoPagerTransactionState; if (cryptoPagerTransactionState != null && cryptoPagerTransactionState.TryGetValue(_dataPager, out var state)) { // we need to iterate from the end in order to filter out pages that was overwritten by later transaction var sortedState = state.OrderByDescending(x => x.Key); var overflowDetector = new RecoveryOverflowDetector(); foreach (var buffer in sortedState) { if (buffer.Value.SkipOnTxCommit) { continue; } if (buffer.Value.Modified == false) { continue; // No modification } var pageHeader = (PageHeader *)buffer.Value.Pointer; var numberOfPages = VirtualPagerLegacyExtensions.GetNumberOfPages(pageHeader); long modifiedPage = buffer.Key; if (overflowDetector.IsOverlappingAnotherPage(modifiedPage, numberOfPages)) { // if page is overlapping an already seen page it means this one was freed, we must skip it on tx commit state[modifiedPage].SkipOnTxCommit = true; continue; } overflowDetector.SetPageChecked(modifiedPage); } } BeforeCommitFinalization?.Invoke(this); } OnDispose?.Invoke(this); }
public void Commit() { if (Flags != TransactionFlags.ReadWrite) { return;// nothing to do } CommitStage1_CompleteTransaction(); if (WriteToJournalIsRequired()) { Environment.LastWorkTime = DateTime.UtcNow; CommitStage2_WriteToJournal(); } BeforeCommitFinalization?.Invoke(this); CommitStage3_DisposeTransactionResources(); }
public void Dispose() { BeforeCommitFinalization?.Invoke(this); OnDispose?.Invoke(this); }