/// <inheritdoc /> public async Task CommitTransactionAsync(CancellationToken cancellationToken = default(CancellationToken)) { EnsureIsInTransaction(nameof(CommitTransaction)); try { if (_currentTransaction.StatementId == 0) { return; } try { var firstAttempt = CreateCommitTransactionOperation(); await ExecuteEndTransactionOnPrimaryAsync(firstAttempt, cancellationToken).ConfigureAwait(false); return; } catch (Exception exception) when(ShouldRetryEndTransactionException(exception)) { // ignore exception and retry } var secondAttempt = CreateCommitTransactionOperation(); await ExecuteEndTransactionOnPrimaryAsync(secondAttempt, cancellationToken).ConfigureAwait(false); } finally { _currentTransaction = null; } }
/// <inheritdoc /> public void AboutToSendCommand() { if (_currentTransaction != null) { switch (_currentTransaction.State) { case CoreTransactionState.Starting: // Starting changes to InProgress after the message is sent to the server case CoreTransactionState.InProgress: return; case CoreTransactionState.Aborted: _currentTransaction = null; break; case CoreTransactionState.Committed: // don't set to null when retrying a commit if (!_isCommitTransactionInProgress) { _currentTransaction = null; } return; default: throw new Exception($"Unexpected transaction state: {_currentTransaction.State}."); } } }
// private methods private CoreTransaction CreateSubject( int statementId = 0, long transactionNumber = 0, TransactionOptions transactionOptions = null) { var subject = new CoreTransaction(transactionNumber, transactionOptions); subject.AdvanceStatementId(statementId); return(subject); }
public void constructor_should_initialize_instance( [Values(1, 2)] long transactionNumber, [Values(false, true)] bool nullTransactionOptions) { var transactionOptions = nullTransactionOptions ? null : new TransactionOptions(); var result = new CoreTransaction(transactionNumber, transactionOptions); result.StatementId.Should().Be(0); result.TransactionNumber.Should().Be(transactionNumber); result.TransactionOptions.Should().BeSameAs(transactionOptions); }
/// <inheritdoc /> public void StartTransaction(TransactionOptions transactionOptions = null) { if (_currentTransaction != null) { throw new InvalidOperationException("Transaction already in progress."); } var transactionNumber = AdvanceTransactionNumber(); var effectiveTransactionOptions = GetEffectiveTransactionOptions(transactionOptions); var transaction = new CoreTransaction(transactionNumber, effectiveTransactionOptions); _currentTransaction = transaction; }
/// <inheritdoc /> public void StartTransaction(TransactionOptions transactionOptions = null) { EnsureStartTransactionCanBeCalled(); var transactionNumber = AdvanceTransactionNumber(); var effectiveTransactionOptions = GetEffectiveTransactionOptions(transactionOptions); if (!effectiveTransactionOptions.WriteConcern.IsAcknowledged) { throw new InvalidOperationException("Transactions do not support unacknowledged write concerns."); } _currentTransaction = new CoreTransaction(transactionNumber, effectiveTransactionOptions); }
/// <inheritdoc /> public void StartTransaction(TransactionOptions transactionOptions = null) { if (_currentTransaction != null) { throw new InvalidOperationException("Transaction already in progress."); } var transactionNumber = AdvanceTransactionNumber(); var readConcern = transactionOptions?.ReadConcern ?? _options.DefaultTransactionOptions?.ReadConcern ?? ReadConcern.Default; var writeConcern = transactionOptions?.WriteConcern ?? _options.DefaultTransactionOptions?.WriteConcern ?? new WriteConcern(); var effectiveTransactionOptions = new TransactionOptions(readConcern, writeConcern); var transaction = new CoreTransaction(transactionNumber, effectiveTransactionOptions); _currentTransaction = transaction; }
// public methods /// <inheritdoc /> public void AbortTransaction(CancellationToken cancellationToken = default(CancellationToken)) { EnsureIsInTransaction(nameof(AbortTransaction)); try { if (_currentTransaction.StatementId == 0) { return; } try { var firstAttempt = CreateAbortTransactionOperation(); ExecuteEndTransactionOnPrimary(firstAttempt, cancellationToken); return; } catch (Exception exception) when(ShouldIgnoreAbortTransactionException(exception)) { return; // ignore exception and return } catch (Exception exception) when(ShouldRetryEndTransactionException(exception)) { // ignore exception and retry } catch { return; // ignore exception and return } try { var secondAttempt = CreateAbortTransactionOperation(); ExecuteEndTransactionOnPrimary(secondAttempt, cancellationToken); } catch { return; // ignore exception and return } } finally { _currentTransaction = null; } }