It looks like when you implement the IManageUnitsOfWork in nservicebus that all handlers ( regardless of if they actually perform any database operations ) cause a transaction to be created and eventually commited/rolled back. Is there significant overhead from this from a high throughput system? Are there any recommended alternatives and examples for getting “full control” over which handlers actually utilize a Database Transaction when executing such as attaching an Attribute to the handler OR creating your own handler base class OR something else?
I assume you’re talking about a TransactionScope, and I don’t think there’s a ton of overhead in creating one, doing nothing with it, and then committing it, because no resource managers would ever enroll. I can’t promise that it’s an effective no-op, but my guess is that you’re edging into a bit of premature optimization here. I wouldn’t worry about it until it’s clear that there’s a problem.
Going further though, it would be very difficult to do anything in an IManageUnitsOfWork just because of what you (don’t) have access to. If you were to rewrite the unit of work implementation as a pipeline behavior, which these days is our preferred approach to a unit of work—or just about any infrastructure need you could think of. From some point in the pipeline, it might be possible to get access to the identified handlers that will be run, do some sort of logic based on that (attribute, etc.) and then decide whether to create a transaction or not.
Our blog post Infrastructure soup has more general information on behaviors in general and how they can be useful.
But like I said, it’s probably YAGNI.