/// <summary> /// Executes the specified asynchronous operation in a transaction and returns the result. Allows to check whether /// the transaction has been rolled back if an error occurs during commit. /// </summary> /// <remarks> /// See <see href="https://aka.ms/efcore-docs-connection-resiliency">Connection resiliency and database retries</see> /// for more information and examples. /// </remarks> /// <param name="strategy">The strategy that will be used for the execution.</param> /// <param name="operation"> /// A function that returns a started task of type <typeparamref name="TResult" />. /// </param> /// <param name="verifySucceeded"> /// A delegate that tests whether the operation succeeded even though an exception was thrown when the /// transaction was being committed. /// </param> /// <param name="cancellationToken"> /// A cancellation token used to cancel the retry operation, but not operations that are already in flight /// or that already completed successfully. /// </param> /// <typeparam name="TResult">The result type of the <see cref="Task{T}" /> returned by <paramref name="operation" />.</typeparam> /// <returns> /// A task that will run to completion if the original task completes successfully (either the /// first time or after retrying transient failures). If the task fails with a non-transient error or /// the retry limit is reached, the returned task will become faulted and the exception must be observed. /// </returns> /// <exception cref="RetryLimitExceededException"> /// The operation has not succeeded after the configured number of retries. /// </exception> /// <exception cref="OperationCanceledException">If the <see cref="CancellationToken" /> is canceled.</exception> public static Task <TResult> ExecuteInTransactionAsync <TResult>( this IExecutionStrategy strategy, Func <CancellationToken, Task <TResult> > operation, Func <CancellationToken, Task <bool> > verifySucceeded, CancellationToken cancellationToken = default) => strategy.ExecuteInTransactionAsync <object?, TResult>( null, (s, ct) => operation(ct), (s, ct) => verifySucceeded(ct), cancellationToken);
/// <summary> /// Executes the specified asynchronous operation in a transaction. Allows to check whether /// the transaction has been rolled back if an error occurs during commit. /// </summary> /// <param name="strategy"> The strategy that will be used for the execution. </param> /// <param name="operation"> /// A function that returns a started task. /// </param> /// <param name="verifySucceeded"> /// A delegate that tests whether the operation succeeded even though an exception was thrown when the /// transaction was being committed. /// </param> /// <param name="cancellationToken"> /// A cancellation token used to cancel the retry operation, but not operations that are already in flight /// or that already completed successfully. /// </param> /// <returns> /// A task that will run to completion if the original task completes successfully (either the /// first time or after retrying transient failures). If the task fails with a non-transient error or /// the retry limit is reached, the returned task will become faulted and the exception must be observed. /// </returns> /// <exception cref="RetryLimitExceededException"> /// The operation has not succeeded after the configured number of retries. /// </exception> public static Task ExecuteInTransactionAsync( [NotNull] this IExecutionStrategy strategy, [NotNull] Func <CancellationToken, Task> operation, [NotNull] Func <CancellationToken, Task <bool> > verifySucceeded, CancellationToken cancellationToken = default) => strategy.ExecuteInTransactionAsync <object>( null, (s, ct) => operation(ct), (s, ct) => verifySucceeded(ct), cancellationToken);
/// <summary> /// Executes the specified asynchronous operation in a transaction and returns the result. Allows to check whether /// the transaction has been rolled back if an error occurs during commit. /// </summary> /// <param name="strategy"> The strategy that will be used for the execution. </param> /// <param name="isolationLevel"> The isolation level to use for the transaction. </param> /// <param name="operation"> /// A function that returns a started task of type <typeparamref name="TResult" />. /// </param> /// <param name="verifySucceeded"> /// A delegate that tests whether the operation succeeded even though an exception was thrown when the /// transaction was being committed. /// </param> /// <param name="cancellationToken"> /// A cancellation token used to cancel the retry operation, but not operations that are already in flight /// or that already completed successfully. /// </param> /// <typeparam name="TResult"> The result type of the <see cref="Task{T}" /> returned by <paramref name="operation" />. </typeparam> /// <returns> /// A task that will run to completion if the original task completes successfully (either the /// first time or after retrying transient failures). If the task fails with a non-transient error or /// the retry limit is reached, the returned task will become faulted and the exception must be observed. /// </returns> /// <exception cref="RetryLimitExceededException"> /// The operation has not succeeded after the configured number of retries. /// </exception> /// <exception cref="OperationCanceledException"> If the <see cref="CancellationToken"/> is canceled. </exception> public static Task <TResult> ExecuteInTransactionAsync <TResult>( [NotNull] this IExecutionStrategy strategy, [NotNull] Func <CancellationToken, Task <TResult> > operation, [NotNull] Func <CancellationToken, Task <bool> > verifySucceeded, IsolationLevel isolationLevel, CancellationToken cancellationToken = default) => strategy.ExecuteInTransactionAsync <object, TResult>( null, (s, ct) => operation(ct), (s, ct) => verifySucceeded(ct), isolationLevel, cancellationToken);
/// <summary> /// Executes the specified asynchronous operation in a transaction. Allows to check whether /// the transaction has been rolled back if an error occurs during commit. /// </summary> /// <param name="strategy"> The strategy that will be used for the execution. </param> /// <param name="isolationLevel"> The isolation level to use for the transaction. </param> /// <param name="operation"> /// A function that returns a started task. /// </param> /// <param name="verifySucceeded"> /// A delegate that tests whether the operation succeeded even though an exception was thrown when the /// transaction was being committed. /// </param> /// <param name="cancellationToken"> /// A cancellation token used to cancel the retry operation, but not operations that are already in flight /// or that already completed successfully. /// </param> /// <returns> /// A task that will run to completion if the original task completes successfully (either the /// first time or after retrying transient failures). If the task fails with a non-transient error or /// the retry limit is reached, the returned task will become faulted and the exception must be observed. /// </returns> /// <exception cref="RetryLimitExceededException"> /// The operation has not succeeded after the configured number of retries. /// </exception> /// <exception cref="OperationCanceledException"> If the <see cref="CancellationToken"/> is canceled. </exception> public static Task ExecuteInTransactionAsync( this IExecutionStrategy strategy, Func <CancellationToken, Task> operation, Func <CancellationToken, Task <bool> > verifySucceeded, IsolationLevel isolationLevel, CancellationToken cancellationToken = default) => strategy.ExecuteInTransactionAsync <object?>( null, (s, ct) => operation(ct), (s, ct) => verifySucceeded(ct), isolationLevel, cancellationToken);
/// <summary> /// Executes the specified asynchronous operation in a transaction. Allows to check whether /// the transaction has been rolled back if an error occurs during commit. /// </summary> /// <param name="strategy"> The strategy that will be used for the execution. </param> /// <param name="state"> The state that will be passed to the operation. </param> /// <param name="operation"> /// A function that returns a started task. /// </param> /// <param name="verifySucceeded"> /// A delegate that tests whether the operation succeeded even though an exception was thrown when the /// transaction was being committed. /// </param> /// <param name="cancellationToken"> /// A cancellation token used to cancel the retry operation, but not operations that are already in flight /// or that already completed successfully. /// </param> /// <typeparam name="TState"> The type of the state. </typeparam> /// <returns> /// A task that will run to completion if the original task completes successfully (either the /// first time or after retrying transient failures). If the task fails with a non-transient error or /// the retry limit is reached, the returned task will become faulted and the exception must be observed. /// </returns> /// <exception cref="RetryLimitExceededException"> /// The operation has not succeeded after the configured number of retries. /// </exception> public static Task ExecuteInTransactionAsync <TState>( [NotNull] this IExecutionStrategy strategy, [CanBeNull] TState state, [NotNull] Func <TState, CancellationToken, Task> operation, [NotNull] Func <TState, CancellationToken, Task <bool> > verifySucceeded, CancellationToken cancellationToken = default(CancellationToken)) => strategy.ExecuteInTransactionAsync(state, async(s, ct) => { await operation(s, ct); return(true); }, verifySucceeded, cancellationToken);
/// <summary> /// Executes the specified asynchronous operation in a transaction. Allows to check whether /// the transaction has been rolled back if an error occurs during commit. /// </summary> /// <remarks> /// See <see href="https://aka.ms/efcore-docs-connection-resiliency">Connection resiliency and database retries</see> /// for more information and examples. /// </remarks> /// <param name="strategy">The strategy that will be used for the execution.</param> /// <param name="state">The state that will be passed to the operation.</param> /// <param name="operation"> /// A function that returns a started task. /// </param> /// <param name="verifySucceeded"> /// A delegate that tests whether the operation succeeded even though an exception was thrown when the /// transaction was being committed. /// </param> /// <param name="cancellationToken"> /// A cancellation token used to cancel the retry operation, but not operations that are already in flight /// or that already completed successfully. /// </param> /// <typeparam name="TState">The type of the state.</typeparam> /// <returns> /// A task that will run to completion if the original task completes successfully (either the /// first time or after retrying transient failures). If the task fails with a non-transient error or /// the retry limit is reached, the returned task will become faulted and the exception must be observed. /// </returns> /// <exception cref="RetryLimitExceededException"> /// The operation has not succeeded after the configured number of retries. /// </exception> /// <exception cref="OperationCanceledException">If the <see cref="CancellationToken" /> is canceled.</exception> public static Task ExecuteInTransactionAsync <TState>( this IExecutionStrategy strategy, TState state, Func <TState, CancellationToken, Task> operation, Func <TState, CancellationToken, Task <bool> > verifySucceeded, CancellationToken cancellationToken = default) => strategy.ExecuteInTransactionAsync( state, async(s, ct) => { await operation(s, ct).ConfigureAwait(false); return(true); }, verifySucceeded, cancellationToken);
/// <summary> /// Executes the specified asynchronous operation in a transaction. Allows to check whether /// the transaction has been rolled back if an error occurs during commit. /// </summary> /// <remarks> /// See <see href="https://aka.ms/efcore-docs-connection-resiliency">Connection resiliency and database retries</see> /// for more information and examples. /// </remarks> /// <param name="strategy">The strategy that will be used for the execution.</param> /// <param name="operation"> /// A function that returns a started task. /// </param> /// <param name="verifySucceeded"> /// A delegate that tests whether the operation succeeded even though an exception was thrown when the /// transaction was being committed. /// </param> /// <returns> /// A task that will run to completion if the original task completes successfully (either the /// first time or after retrying transient failures). If the task fails with a non-transient error or /// the retry limit is reached, the returned task will become faulted and the exception must be observed. /// </returns> /// <exception cref="RetryLimitExceededException"> /// The operation has not succeeded after the configured number of retries. /// </exception> public static Task ExecuteInTransactionAsync( this IExecutionStrategy strategy, Func <Task> operation, Func <Task <bool> > verifySucceeded) => strategy.ExecuteInTransactionAsync <object?>(null, (s, ct) => operation(), (s, ct) => verifySucceeded());
/// <summary> /// Executes the specified asynchronous operation in a transaction. Allows to check whether /// the transaction has been rolled back if an error occurs during commit. /// </summary> /// <param name="strategy"> The strategy that will be used for the execution. </param> /// <param name="isolationLevel"> The isolation level to use for the transaction. </param> /// <param name="operation"> /// A function that returns a started task. /// </param> /// <param name="verifySucceeded"> /// A delegate that tests whether the operation succeeded even though an exception was thrown when the /// transaction was being committed. /// </param> /// <returns> /// A task that will run to completion if the original task completes successfully (either the /// first time or after retrying transient failures). If the task fails with a non-transient error or /// the retry limit is reached, the returned task will become faulted and the exception must be observed. /// </returns> /// <exception cref="RetryLimitExceededException"> /// The operation has not succeeded after the configured number of retries. /// </exception> public static Task ExecuteInTransactionAsync( [NotNull] this IExecutionStrategy strategy, [NotNull] Func <Task> operation, [NotNull] Func <Task <bool> > verifySucceeded, IsolationLevel isolationLevel) => strategy.ExecuteInTransactionAsync <object>(null, (s, ct) => operation(), (s, ct) => verifySucceeded(), isolationLevel);
/// <summary> /// Executes the specified asynchronous operation in a transaction. Allows to check whether /// the transaction has been rolled back if an error occurs during commit. /// </summary> /// <remarks> /// See <see href="https://aka.ms/efcore-docs-connection-resiliency">Connection resiliency and database retries</see> /// for more information and examples. /// </remarks> /// <param name="strategy">The strategy that will be used for the execution.</param> /// <param name="isolationLevel">The isolation level to use for the transaction.</param> /// <param name="operation"> /// A function that returns a started task. /// </param> /// <param name="verifySucceeded"> /// A delegate that tests whether the operation succeeded even though an exception was thrown when the /// transaction was being committed. /// </param> /// <returns> /// A task that will run to completion if the original task completes successfully (either the /// first time or after retrying transient failures). If the task fails with a non-transient error or /// the retry limit is reached, the returned task will become faulted and the exception must be observed. /// </returns> /// <exception cref="RetryLimitExceededException"> /// The operation has not succeeded after the configured number of retries. /// </exception> public static Task ExecuteInTransactionAsync( this IExecutionStrategy strategy, Func <Task> operation, Func <Task <bool> > verifySucceeded, IsolationLevel isolationLevel) => strategy.ExecuteInTransactionAsync <object?>(null, (_, _) => operation(), (_, _) => verifySucceeded(), isolationLevel);