/// <summary> /// Convenience method for adding an item easily to the Transactional Outbox using Default implementations (e.g. GUID identifier). /// This method will create and commit the Transaction automatically, but may error if a running transaction /// is already in progress in which case the custom extension of the Transaction should be used directly instead. /// </summary> /// <typeparam name="TPayload"></typeparam> /// <param name="sqlConnection"></param> /// <param name="publishTarget"></param> /// <param name="payload"></param> /// <param name="fifoGroupingIdentifier"></param> /// <returns></returns> public static async Task <ISqlTransactionalOutboxItem <Guid> > AddTransactionalOutboxPendingItemAsync <TPayload>( this SqlConnection sqlConnection, string publishTarget, TPayload payload, string fifoGroupingIdentifier = null ) { sqlConnection.AssertSqlConnectionIsValid(); await using var outboxTransaction = (SqlTransaction)(await sqlConnection.BeginTransactionAsync().ConfigureAwait(false)); try { var results = await outboxTransaction .AddTransactionalOutboxPendingItemAsync(publishTarget, payload, fifoGroupingIdentifier) .ConfigureAwait(false); await outboxTransaction.CommitAsync().ConfigureAwait(false); return(results); } catch (Exception) { await outboxTransaction.RollbackAsync().ConfigureAwait(false); throw; } }
/// <summary> /// Convenience method for adding an item easily to the Transactional Outbox using Default implementations (e.g. GUID identifier). /// This method will create and commit the Transaction automatically, but may error if a running transaction /// is already in progress in which case the custom extension of the Transaction should be used directly instead. /// </summary> /// <typeparam name="TPayload"></typeparam> /// <param name="sqlConnection"></param> /// <param name="outboxInsertionItems"></param> /// <returns></returns> public static async Task <List <ISqlTransactionalOutboxItem <Guid> > > AddTransactionalOutboxPendingItemListAsync <TPayload>( this SqlConnection sqlConnection, IEnumerable <ISqlTransactionalOutboxInsertionItem <TPayload> > outboxInsertionItems ) { sqlConnection.AssertSqlConnectionIsValid(); await using var outboxTransaction = (SqlTransaction)(await sqlConnection.BeginTransactionAsync().ConfigureAwait(false)); try { var results = await outboxTransaction .AddTransactionalOutboxPendingItemListAsync(outboxInsertionItems) .ConfigureAwait(false); await outboxTransaction.CommitAsync().ConfigureAwait(false); return(results); } catch (Exception) { await outboxTransaction.RollbackAsync().ConfigureAwait(false); throw; } }
public static async Task <ISqlTransactionalOutboxProcessingResults <Guid> > ProcessPendingOutboxItemsAsync( this SqlConnection sqlConnection, ISqlTransactionalOutboxPublisher <Guid> outboxPublisher, OutboxProcessingOptions processingOptions, bool throwExceptionOnFailure = false ) { sqlConnection.AssertSqlConnectionIsValid(); outboxPublisher.AssertNotNull(nameof(outboxPublisher)); processingOptions.AssertNotNull(nameof(processingOptions)); await using var outboxTransaction = (SqlTransaction)(await sqlConnection.BeginTransactionAsync().ConfigureAwait(false)); try { var results = await outboxTransaction .ProcessPendingOutboxItemsAsync( outboxPublisher : outboxPublisher, processingOptions : processingOptions, throwExceptionOnFailure : throwExceptionOnFailure ) .ConfigureAwait(false); await outboxTransaction.CommitAsync().ConfigureAwait(false); return(results); } catch (Exception) { await outboxTransaction.RollbackAsync().ConfigureAwait(false); throw; } }
public static async Task <ISqlTransactionalOutboxProcessingResults <Guid> > ProcessPendingOutboxItemsAsync( this SqlConnection sqlConnection, ISqlTransactionalOutboxPublisher <Guid> outboxPublisher, OutboxProcessingOptions processingOptions, bool throwExceptionOnFailure = false ) { sqlConnection.AssertSqlConnectionIsValid(); outboxPublisher.AssertNotNull(nameof(outboxPublisher)); processingOptions.AssertNotNull(nameof(processingOptions)); await using var outboxTransaction = (SqlTransaction)(await sqlConnection.BeginTransactionAsync().ConfigureAwait(false)); try { var results = await outboxTransaction .ProcessPendingOutboxItemsAsync( outboxPublisher : outboxPublisher, processingOptions : processingOptions, throwExceptionOnFailure : throwExceptionOnFailure ) .ConfigureAwait(false); await outboxTransaction.CommitAsync().ConfigureAwait(false); return(results); } catch (Exception exc) { //FIRST Rollback any pending changes... await outboxTransaction.RollbackAsync().ConfigureAwait(false); try { //THEN Attempt any Mitigating Actions for the Issue... //IF WE have issues retrieving the new items from the DB then we attempt to increment the // Publish Attempts in case there is an issue with the entry that is causing failures, so // that any potential problematic items will eventually be failed out and skipped. await sqlConnection.IncrementPublishAttemptsForAllPendingItemsAsync(outboxPublisher).ConfigureAwait(false); } catch (Exception mitigationExc) { throw new AggregateException(new[] { exc, mitigationExc }); } //FINALLY Re-throw to ensure we don't black hole the issue... throw; } }
/// <summary> /// Execute the cleanup (e.g. Purge) of Historical data from the Outbox for the specified timespan /// of how much time to keep (e.g. last 30 days, last 90 days, etc.). /// This method will create and commit the Transaction automatically, but may error if a running transaction /// is already in progress in which case the custom extension of the Transaction should be used directly instead. /// </summary> /// <param name="sqlConnection"></param> /// <param name="historyTimeToKeepTimeSpan"></param> /// <returns></returns> public static async Task CleanupHistoricalOutboxItemsAsync( this SqlConnection sqlConnection, TimeSpan historyTimeToKeepTimeSpan ) { sqlConnection.AssertSqlConnectionIsValid(); await using var outboxTransaction = (SqlTransaction)(await sqlConnection.BeginTransactionAsync().ConfigureAwait(false)); try { await outboxTransaction .CleanupHistoricalOutboxItemsAsync(historyTimeToKeepTimeSpan) .ConfigureAwait(false); await outboxTransaction.CommitAsync().ConfigureAwait(false); } catch (Exception) { await outboxTransaction.RollbackAsync().ConfigureAwait(false); throw; } }