Open JornWildt opened 1 year ago
Hmm curious as you made me I went through QuickWatch reflection on SqlConnection
, and as you can see there's a SqlTransaction
hiding in there, which can be retrieved through some private properties:
I then coded this little example to see if I could actually get it to work. The central bits look somewhat like this:
static SqlTransaction GetSqlTransactionViaReflection(SqlConnection connection)
{
const BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
var innerConnectionField = connection.GetType().GetProperty("InnerConnection", flags);
var innerConnection = innerConnectionField?.GetValue(connection);
var availableInnerTransactionField = innerConnection?.GetType().GetProperty("AvailableInternalTransaction", flags);
var availableInnerTransaction = availableInnerTransactionField?.GetValue(innerConnection);
var parentTransactionField = availableInnerTransaction?.GetType().GetProperty("Parent", flags);
var parentTransaction = parentTransactionField?.GetValue(availableInnerTransaction) as SqlTransaction;
return parentTransaction;
}
It succeeds in retrieving the SqlTransaction
when it's an ordinary, manually started transaction, but it fails when the transaction is an ambient one started by the TransactionScope
.
I have not been able to figure out a way to retrieve the transaction in any other way.
Maybe it would be a nice addition to the API to enable doing something like this:
// somewhere, possibly far out in the call hierarchy
using var txScope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled);
// further down:
using var scope = new RebusTransactionScope();
scope.UseOutboxWithAmbientTransaction();
// whee!
I don't think it would be too hard to enable this, but it's hard to tell if there's a surprise or two lurking in there.
Thanks for your work! scope.UseOutboxWithAmbientTransaction();
seems to fit my exact use case where my framework uses TransactionScope
all over the place. Should you ever find time to add it, then please ping me here :-)
BTW it is Cofoundry: https://www.cofoundry.org/docs/framework/data-access/transactions
The current Outbox implementation requires both an SqlConnection as well as an SqlTransaction as shown on https://github.com/rebus-org/Rebus/wiki/Outbox :
Unfortunately I work with a framework that uses TransactionScope - and I have found no way to get the SqlTransaction out of that.
Is there any way to get SqlTransaction out of SqlConnection (I haven't found one)?
Would it be possible to expand the Outbox implementation to work with TransactionScope in addition to SqlTransaction?