/// <summary> /// This begins an async commit and starts a new transaction immediately. /// The current transaction is considered completed in memory but not yet /// committed to disk. This *must* be completed by calling EndAsyncCommit. /// </summary> public LowLevelTransaction BeginAsyncCommitAndStartNewTransaction() { if (Flags != TransactionFlags.ReadWrite) { ThrowReadTranscationCannotDoAsyncCommit(); } if (_asyncCommitNextTransaction != null) { ThrowAsyncCommitAlreadyCalled(); } // we have to check the state before we complete the transaction // because that would change whether we need to write to the journal var writeToJournalIsRequired = WriteToJournalIsRequired(); CommitStage1_CompleteTransaction(); var nextTx = new LowLevelTransaction(this, writeToJournalIsRequired ? Id + 1 : Id ); _asyncCommitNextTransaction = nextTx; AsyncCommit = writeToJournalIsRequired ? Task.Run(() => { CommitStage2_WriteToJournal(); return(true); }) : NoWriteToJournalRequiredTask; try { _env.IncrementUsageOnNewTransaction(); _env.ActiveTransactions.Add(nextTx); _env.WriteTransactionStarted(); return(nextTx); } catch (Exception) { // failure here means that we'll try to complete the current transaction normaly // then throw as if commit was called normally and the next transaction failed _env.DecrementUsageOnTransactionCreationFailure(); EndAsyncCommit(); AsyncCommit = null; _disposed |= TxState.Errored; throw; } }