private async Task <TResponse> HandleTransactionalRequest(TRequest request, RequestHandlerDelegate <TResponse> next, CancellationToken cancellationToken) { var response = default(TResponse); var typeName = request.GetGenericTypeName(); try { if (_transactionalUnitOfWork.TransactionInProgress) { return(await next()); } var strategy = _transactionalUnitOfWork.CreateExecutionStrategy(); await strategy.ExecuteAsync(async() => { Guid transactionId; await using var transaction = await _transactionalUnitOfWork.BeginTransactionAsync(cancellationToken); using (LogContext.PushProperty("TransactionContext", transaction.TransactionId)) { _logger.LogInformation("----- Begin transaction {TransactionId} for {CommandName} ({@Command})", transaction.TransactionId, typeName, request); response = await next(); _logger.LogInformation("----- Commit transaction {TransactionId} for {CommandName}", transaction.TransactionId, typeName); // this is always a matter to discuss inside the team, do you prefer to commit before // publishing integration events or after them ??? await _transactionalUnitOfWork.CommitTransactionAsync(transaction, cancellationToken); transactionId = transaction.TransactionId; } // this is after the commit, so if it fails we can try them later on in a message relay, for instance. if (_transactionalOutboxConfiguration.AutoPublish) { await _transactionalOutboxService.PublishEventsThroughEventBusAsync(transactionId); } // // this is always a matter to discuss inside the team, do you prefer to commit before // // publishing integration events or after them ??? // await _transactionalUnitOfWork.CommitTransactionAsync(transaction, cancellationToken); }); return(response); } catch (Exception ex) { _logger.LogError(ex, "ERROR Handling transaction for {CommandName} ({@Command})", typeName, request); return(response); } }
public async Task HandleAsync(TCommand command) { if (_unitOfWork.HasActiveTransaction) { await _decoratedHandler.HandleAsync(command); } else { await using var transaction = await _unitOfWork.BeginTransactionAsync(); await _decoratedHandler.HandleAsync(command); await _unitOfWork.CommitTransactionAsync(transaction !); } }