Ensuring consistency using NServiceBus with AWS SQS transport

Hi,
Consider this simple scenario:

HTTP PUT request is called on a “CreateUser” API.
When handling that request in the controller, we want to
a) store the business data changes
b) publish integration events to multiple subscribers after the fact

public async Task<IActionResult> CreateUser(...
	// a: store the business data changes in a postgresql db
	await userRepository.Save(user);
	// b: publish integration events to multiple subscribers after the fact, using NServiceBus/SQS
	foreach (var @event in user.Events)
		await context.Publish(@event);

The system (the publisher and all subscribers) needs to be eventual consistent, so:
If “a” fails, we don’t want to publish an event. Easy.

But if “b” fails, we are screwed, especially if some of the Publish calls already suceeded.
Usually I would solve this by using an outbox pattern and publish the messages in a completely seperate process.
But I was wondering if NServiceBus already had an answer to this common challenge? Something in the line of what “Jasper” supports: Jasper’s “Outbox” Pattern Support – The Shade Tree Developer

I know NServiceBus has an outbox feature, but it only works within a message handler context so it does not really apply to this scenario.

Hi Martin,

An easy way to decouple the business process from the incoming HTTP request is by sending a message locally to yourself and then in the context of that message do what you plan to do using also the Outbox.

HTH,
.m

Good idea.
I already use a command pattern internally in the service (using something like MediatR). I guess if I just replaced the MediatR style plumming with some “SendLocal” NServiceBus stuff, I would be flying :slight_smile:

Also note that the Jasper/Marten “outbox” is slightly different in that it doesn’t (yet) have any deduplication support should you need that

https://twitter.com/jeremydmiller/status/1006147035836420096

1 Like