Is the following C# code guaranteed to have always sent a message if it is recorded as having been sent in the database, or does the ConfigureAwait(false) mean it is possible to have recorded something as sent in the Db even if it was not sent, say if network failed at just the right moment.
This does an exception propagate? seems to indicate exceptions might not always propagate due to the ConfigureAwait(false)
public async Send(string message){
await using var transaction = await _dbContext.BeginTransactionAsync(cancellationToken);
_dbContext.SentEvents.Add(message);
await _dbContext.SaveChangesAsync();
await _publisher.PublishAsync(message).ConfigureAwait(false);
await transaction.CommitAsync();
}
The reason I ask it it seems, Azure.Messaging.ServiceBus.ServiceBusSender 7.10.0.0 uses ConfigureAwait(false) internally. Assume for the sake of the question that _dbContext is microsoft entity framework and the transaction an Microsoft.EntityFrameworkCore.Storage.IDbContextTransaction
Or is there a better way of only persisting a record of a message as having been sent in the DB only if it sent by ServiceBusSender? So we can guarantee at least once delivery.
Yes.
The linked question never provided a reproducible test case. No one except the op ever observed that behavior.
ConfigureAwait(false)has no effect on exception propagation. The exception will propagate (preventing the transaction from completing) with or withoutConfigureAwait(false).It's a bit unusual to keep the message in the db after it's sent; the more common pattern is to delete the message in the db after it's sent. That said, this code should work fine. The Googleable term is "outbox pattern".