Ejemplo n.º 1
0
        /// <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;
            }
        }