From d6f0ede9746a3f655c9b3897031e3925dc015d80 Mon Sep 17 00:00:00 2001 From: John Simons Date: Mon, 27 Oct 2014 13:38:40 +1000 Subject: [PATCH 1/3] Correct defaults for suppressing the ambient tx --- .../NServiceBus.AcceptanceTests.csproj | 3 +- .../Tx/Issue_2481.cs | 58 +++++++++++++++++++ src/NServiceBus.Core/BusConfiguration.cs | 53 +++++++++-------- .../Settings/TransactionSettings.cs | 6 +- 4 files changed, 89 insertions(+), 31 deletions(-) create mode 100644 src/NServiceBus.AcceptanceTests/Tx/Issue_2481.cs diff --git a/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj b/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj index 92181ed356b..3d7d81a48e4 100644 --- a/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj +++ b/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj @@ -1,4 +1,4 @@ - + @@ -67,6 +67,7 @@ + diff --git a/src/NServiceBus.AcceptanceTests/Tx/Issue_2481.cs b/src/NServiceBus.AcceptanceTests/Tx/Issue_2481.cs new file mode 100644 index 00000000000..0678b25115a --- /dev/null +++ b/src/NServiceBus.AcceptanceTests/Tx/Issue_2481.cs @@ -0,0 +1,58 @@ +namespace NServiceBus.AcceptanceTests.Tx +{ + using System; + using System.Transactions; + using NServiceBus.AcceptanceTesting; + using NServiceBus.AcceptanceTests.EndpointTemplates; + using NServiceBus.AcceptanceTests.ScenarioDescriptors; + using NUnit.Framework; + + public class Issue_2481 : NServiceBusAcceptanceTest + { + [Test] + public void Should_enlist_the_receive_in_the_dtc_tx() + { + Scenario.Define() + .WithEndpoint(b => b.Given(bus => bus.SendLocal(new MyMessage()))) + .Done(c => c.HandlerInvoked) + .Repeat(r => r.For()) + .Should(c => Assert.False(c.CanEnlistPromotable, "There should exists a DTC tx")) + .Run(); + } + + + public class Context : ScenarioContext + { + public bool HandlerInvoked { get; set; } + + public bool CanEnlistPromotable { get; set; } + } + + public class DTCEndpoint : EndpointConfigurationBuilder + { + public DTCEndpoint() + { + EndpointSetup(c=>c.Transactions().Enable()); + } + + public class MyMessageHandler : IHandleMessages + { + public Context Context { get; set; } + + public void Handle(MyMessage messageThatIsEnlisted) + { + Context.CanEnlistPromotable = Transaction.Current.EnlistPromotableSinglePhase(new FakePromotableResourceManager()); + Context.HandlerInvoked = true; + } + } + } + + [Serializable] + public class MyMessage : ICommand + { + } + + + + } +} diff --git a/src/NServiceBus.Core/BusConfiguration.cs b/src/NServiceBus.Core/BusConfiguration.cs index ec85a5d6dcb..94642aff84b 100644 --- a/src/NServiceBus.Core/BusConfiguration.cs +++ b/src/NServiceBus.Core/BusConfiguration.cs @@ -33,6 +33,13 @@ public BusConfiguration() : base(new SettingsHolder()) configurationSourceToUse = new DefaultConfigurationSource(); Settings.Set(new PipelineModifications()); Pipeline = new PipelineSettings(this); + + Settings.SetDefault("Endpoint.SendOnly", false); + Settings.SetDefault("Transactions.Enabled", true); + Settings.SetDefault("Transactions.IsolationLevel", IsolationLevel.ReadCommitted); + Settings.SetDefault("Transactions.DefaultTimeout", TransactionManager.DefaultTimeout); + Settings.SetDefault("Transactions.SuppressDistributedTransactions", false); + Settings.SetDefault("Transactions.DoNotWrapHandlersExecutionInATransactionScope", false); } /// @@ -195,7 +202,25 @@ internal Configure BuildConfiguration() UseTransportExtensions.SetupTransport(this); var container = customBuilder ?? new AutofacObjectBuilder(); - RegisterEndpointWideDefaults(); + + Settings.SetDefault(configurationSourceToUse); + Settings.SetDefault("TypesToScan", scannedTypes); + + var endpointHelper = new EndpointHelper(new StackTrace()); + + if (endpointVersion == null) + { + endpointVersion = endpointHelper.GetEndpointVersion(); + } + + if (endpointName == null) + { + endpointName = endpointHelper.GetDefaultEndpointName(); + } + + Settings.SetDefault("EndpointName", endpointName); + Settings.SetDefault("EndpointVersion", endpointVersion); + if (publicReturnAddress != null) { @@ -224,32 +249,6 @@ IEnumerable GetAssembliesInDirectory(string path, params string[] asse .Assemblies; } - void RegisterEndpointWideDefaults() - { - var endpointHelper = new EndpointHelper(new StackTrace()); - - if (endpointVersion == null) - { - endpointVersion = endpointHelper.GetEndpointVersion(); - } - - if (endpointName == null) - { - endpointName = endpointHelper.GetDefaultEndpointName(); - } - - Settings.SetDefault("EndpointName", endpointName); - Settings.SetDefault("TypesToScan", scannedTypes); - Settings.SetDefault("EndpointVersion", endpointVersion); - Settings.SetDefault("Endpoint.SendOnly", false); - Settings.SetDefault("Transactions.Enabled", true); - Settings.SetDefault("Transactions.IsolationLevel", IsolationLevel.ReadCommitted); - Settings.SetDefault("Transactions.DefaultTimeout", TransactionManager.DefaultTimeout); - Settings.SetDefault("Transactions.SuppressDistributedTransactions", false); - Settings.SetDefault("Transactions.DoNotWrapHandlersExecutionInATransactionScope", false); - Settings.SetDefault(configurationSourceToUse); - } - IConfigurationSource configurationSourceToUse; ConventionsBuilder conventionsBuilder = new ConventionsBuilder(); List> registrations = new List>(); diff --git a/src/NServiceBus.Core/Settings/TransactionSettings.cs b/src/NServiceBus.Core/Settings/TransactionSettings.cs index 5082acee0f1..241d64b2bc7 100644 --- a/src/NServiceBus.Core/Settings/TransactionSettings.cs +++ b/src/NServiceBus.Core/Settings/TransactionSettings.cs @@ -23,7 +23,7 @@ internal TransactionSettings(BusConfiguration config) public TransactionSettings Disable() { config.Settings.Set("Transactions.Enabled", false); - config.Settings.SetDefault("Transactions.DoNotWrapHandlersExecutionInATransactionScope", false); + config.Settings.SetDefault("Transactions.DoNotWrapHandlersExecutionInATransactionScope", true); config.Settings.SetDefault("Transactions.SuppressDistributedTransactions", true); return this; @@ -35,7 +35,7 @@ public TransactionSettings Disable() public TransactionSettings Enable() { config.Settings.Set("Transactions.Enabled", true); - config.Settings.SetDefault("Transactions.DoNotWrapHandlersExecutionInATransactionScope", true); + config.Settings.SetDefault("Transactions.DoNotWrapHandlersExecutionInATransactionScope", false); config.Settings.SetDefault("Transactions.SuppressDistributedTransactions", false); return this; @@ -61,7 +61,7 @@ public TransactionSettings IsolationLevel(IsolationLevel isolationLevel) public TransactionSettings DisableDistributedTransactions() { config.Settings.Set("Transactions.SuppressDistributedTransactions", true); - config.Settings.SetDefault("Transactions.DoNotWrapHandlersExecutionInATransactionScope", false); + config.Settings.SetDefault("Transactions.DoNotWrapHandlersExecutionInATransactionScope", true); return this; } From eec009b75aab818e3c3d29ba0c831a8c16b0c11c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96hlund?= Date: Thu, 23 Oct 2014 15:07:21 +0200 Subject: [PATCH 2/3] Letting the ambient transaction control if we enlist or not If not the send won't enlist in ambient transactions --- src/NServiceBus.Core/Transports/Msmq/MsmqMessageSender.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/NServiceBus.Core/Transports/Msmq/MsmqMessageSender.cs b/src/NServiceBus.Core/Transports/Msmq/MsmqMessageSender.cs index 3174b4bacfe..176bf758469 100644 --- a/src/NServiceBus.Core/Transports/Msmq/MsmqMessageSender.cs +++ b/src/NServiceBus.Core/Transports/Msmq/MsmqMessageSender.cs @@ -97,11 +97,6 @@ MessageQueueTransactionType GetTransactionTypeForSend() return MessageQueueTransactionType.None; } - if (SuppressDistributedTransactions) - { - return MessageQueueTransactionType.Single; - } - return Transaction.Current != null ? MessageQueueTransactionType.Automatic : MessageQueueTransactionType.Single; From 23bab6025f4d6c814058544b89b0d1335706bfc4 Mon Sep 17 00:00:00 2001 From: John Simons Date: Mon, 27 Oct 2014 11:45:07 +1000 Subject: [PATCH 3/3] INeedInitialization not called early enough. This causes transport, conventions, endpointname and endpointversion not being picked up if configured in INeedInitialization. Fixes #2530 --- .../Basic/When_using_ineedinitialization.cs | 101 ++++++++++++++++++ .../NServiceBus.AcceptanceTests.csproj | 3 +- src/NServiceBus.Core/BusConfiguration.cs | 8 +- 3 files changed, 107 insertions(+), 5 deletions(-) create mode 100644 src/NServiceBus.AcceptanceTests/Basic/When_using_ineedinitialization.cs diff --git a/src/NServiceBus.AcceptanceTests/Basic/When_using_ineedinitialization.cs b/src/NServiceBus.AcceptanceTests/Basic/When_using_ineedinitialization.cs new file mode 100644 index 00000000000..cd28866b418 --- /dev/null +++ b/src/NServiceBus.AcceptanceTests/Basic/When_using_ineedinitialization.cs @@ -0,0 +1,101 @@ +namespace NServiceBus.AcceptanceTests.Basic +{ + using System; + using NServiceBus.AcceptanceTesting; + using NServiceBus.AcceptanceTests.EndpointTemplates; + using NUnit.Framework; + + public class When_using_ineedinitialization : NServiceBusAcceptanceTest + { + [Test] + public void Should_be_able_to_set_endpoint_name() + { + var context = new Context(); + + Scenario.Define(context) + .WithEndpoint() + .WithEndpoint() + .Done(c => c.WasCalled) + .Run(); + + Assert.True(context.WasCalled, "The message handler should be called"); + } + + public class Context : ScenarioContext + { + public bool WasCalled { get; set; } + } + + public class Sender : EndpointConfigurationBuilder + { + public Sender() + { + EndpointSetup(); + } + } + + public class Receiver : EndpointConfigurationBuilder + { + public Receiver() + { + EndpointSetup() + .AddMapping(typeof(Sender)); + } + + public class SetEndpointName : INeedInitialization + { + public void Customize(BusConfiguration config) + { + config.EndpointName("ineedinitialization_receiver"); + } + } + + public class SendMessageToSender: IWantToRunWhenBusStartsAndStops + { + public IBus Bus { get; set; } + + public void Start() + { + Bus.Send(new SendMessage()); + } + + public void Stop() + { + } + } + } + + [Serializable] + public class SendMessage : ICommand + { + } + + [Serializable] + public class MyMessage : ICommand + { + public Guid Id { get; set; } + } + + public class SendMessageHandler : IHandleMessages + { + public IBus Bus { get; set; } + + public void Handle(SendMessage message) + { + Bus.Send("ineedinitialization_receiver", new MyMessage()); + } + } + + public class MyMessageHandler : IHandleMessages + { + public Context Context { get; set; } + + public IBus Bus { get; set; } + + public void Handle(MyMessage message) + { + Context.WasCalled = true; + } + } + } +} diff --git a/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj b/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj index 3d7d81a48e4..f5c3a0c32cc 100644 --- a/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj +++ b/src/NServiceBus.AcceptanceTests/NServiceBus.AcceptanceTests.csproj @@ -1,4 +1,4 @@ - + @@ -52,6 +52,7 @@ + diff --git a/src/NServiceBus.Core/BusConfiguration.cs b/src/NServiceBus.Core/BusConfiguration.cs index 94642aff84b..6c9f19ff8fa 100644 --- a/src/NServiceBus.Core/BusConfiguration.cs +++ b/src/NServiceBus.Core/BusConfiguration.cs @@ -200,11 +200,14 @@ internal Configure BuildConfiguration() } } + Settings.SetDefault("TypesToScan", scannedTypes); + + Configure.ActivateAndInvoke(scannedTypes, t => t.Customize(this)); + UseTransportExtensions.SetupTransport(this); var container = customBuilder ?? new AutofacObjectBuilder(); Settings.SetDefault(configurationSourceToUse); - Settings.SetDefault("TypesToScan", scannedTypes); var endpointHelper = new EndpointHelper(new StackTrace()); @@ -221,7 +224,6 @@ internal Configure BuildConfiguration() Settings.SetDefault("EndpointName", endpointName); Settings.SetDefault("EndpointVersion", endpointVersion); - if (publicReturnAddress != null) { Settings.SetDefault("PublicReturnAddress", publicReturnAddress); @@ -231,8 +233,6 @@ internal Configure BuildConfiguration() Settings.SetDefault(conventionsBuilder.Conventions); - Configure.ActivateAndInvoke(scannedTypes, t => t.Customize(this)); - return new Configure(Settings, container, registrations, Pipeline); }