From 615ab36180f998cde6b49550cba748b8312f9fde Mon Sep 17 00:00:00 2001 From: David Boike Date: Mon, 21 Jun 2021 09:26:09 -0500 Subject: [PATCH] Better DTC check, doesn't even open connection on netcore (#860) --- .../SqlServerTransportInfrastructure.cs | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/NServiceBus.Transport.SqlServer/SqlServerTransportInfrastructure.cs b/src/NServiceBus.Transport.SqlServer/SqlServerTransportInfrastructure.cs index d7b21a235..72835a9d6 100644 --- a/src/NServiceBus.Transport.SqlServer/SqlServerTransportInfrastructure.cs +++ b/src/NServiceBus.Transport.SqlServer/SqlServerTransportInfrastructure.cs @@ -266,10 +266,16 @@ async Task TryEscalateToDistributedTransactions(TransactionO try { using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew, transactionOptions, TransactionScopeAsyncFlowOption.Enabled)) - using (await connectionFactory.OpenNewConnection().ConfigureAwait(false)) - using (await connectionFactory.OpenNewConnection().ConfigureAwait(false)) { - scope.Complete(); + FakePromotableResourceManager.ForceDtc(); + using (await connectionFactory.OpenNewConnection().ConfigureAwait(false)) + { + FakePromotableResourceManager.ForceDtc(); + using (await connectionFactory.OpenNewConnection().ConfigureAwait(false)) + { + scope.Complete(); + } + } } } catch (NotSupportedException ex) @@ -281,13 +287,13 @@ async Task TryEscalateToDistributedTransactions(TransactionO "Note that different transaction modes may affect consistency guarantees as you can't rely on distributed " + "transactions to atomically update the database and consume a message. Original error message: " + ex.Message; } - catch (SqlException sqlException) + catch (Exception exception) { message = "Could not escalate to a distributed transaction while configured to use TransactionScope. Check original error message for details. " + "In case the problem is related to distributed transactions you can still use SQL Server transport but " + "should specify a different transaction mode via `EndpointConfiguration.UseTransport().Transactions`. " + "Note that different transaction modes may affect consistency guarantees as you can't rely on distributed " + - "transactions to atomically update the database and consume a message. Original error message: " + sqlException.Message; + "transactions to atomically update the database and consume a message. Original error message: " + exception.Message; } if (!string.IsNullOrWhiteSpace(message)) @@ -360,6 +366,17 @@ public override string MakeCanonicalForm(string transportAddress) return addressTranslator.Parse(transportAddress).Address; } + class FakePromotableResourceManager : IEnlistmentNotification + { + public static readonly Guid Id = Guid.NewGuid(); + public void Prepare(PreparingEnlistment preparingEnlistment) => preparingEnlistment.Prepared(); + public void Commit(Enlistment enlistment) => enlistment.Done(); + public void Rollback(Enlistment enlistment) => enlistment.Done(); + public void InDoubt(Enlistment enlistment) => enlistment.Done(); + + public static void ForceDtc() => Transaction.Current.EnlistDurable(Id, new FakePromotableResourceManager(), EnlistmentOptions.None); + } + QueueAddressTranslator addressTranslator; string connectionString; Func localAddress;