Transaction Timeout while dequeueing the message

514 views
Skip to first unread message

Van Thi

unread,
Oct 22, 2015, 4:25:21 AM10/22/15
to Particular Software
Hi all,
We get this exception inside the command/event handlers. From our investigation it happens if the handler takes more than 1 minutes to complete, while the default transaction is documented as 10 minutes at: http://docs.particular.net/nservicebus/operations/transactions-message-processing.
When this exception is thrown the message gets retried and so if inside the handler you publish or send it to another endpoint, this will be done twice. Why NSB can't detect this case so that it will not send or publish the duplicated message?
On the receiver endpoint it also can't detect that the message is duplicated so it processes message twice.
Does anyone have good idea to handle this scenario? We're using NSB 4.6.5.

 NServiceBus.Unicast.Transport.TransportReceiver [(null)] - Failed to process message
System.Transactions.TransactionAbortedException: The transaction has aborted. ---> System.TimeoutException: Transaction Timeout
   --- End of inner exception stack trace ---
   at System.Transactions.TransactionStatePromotedAborted.BeginCommit(InternalTransaction tx, Boolean asyncCommit, AsyncCallback asyncCallback, Object asyncState)
   at System.Transactions.CommittableTransaction.Commit()
   at System.Transactions.TransactionScope.InternalDispose()
   at System.Transactions.TransactionScope.Dispose()
   at NServiceBus.Transports.Msmq.MsmqDequeueStrategy.Action() in c:\BuildAgent\work\1b05a2fea6e4cd32\src\NServiceBus.Core\Transports\Msmq\MsmqDequeueStrategy.cs:line 240

Thanks for your reading & for any suggestion!
Van Thi

tim.bu...@particular.net

unread,
Oct 22, 2015, 6:06:43 AM10/22/15
to Particular Software
did you explicitly disable transactions? Since you're using MSMQ, by default all messages sent/published from a handler are rolled back too in case the transaction is aborted.

Van Thi

unread,
Oct 23, 2015, 4:43:56 AM10/23/15
to Particular Software
Hi Tim
Thanks for your answer!
I do not explicitly disable the transaction, I just enable the option "DoNotWrapHandlersExecutionInATransactionScope".
Here is my configuration code:

Configure.Transactions.Advanced(x => x.DoNotWrapHandlersExecutionInATransactionScope());
Bus = Configure.With()
                   .DefineEndpointName(Settings.Default.EndpointName)
                   .AutofacBuilder(Container)
                   .UseNHibernateSubscriptionPersister()
                   .UseNHibernateTimeoutPersister(NHibernateConfig.GetConfig(), true)
                    .UnicastBus()
                    .CreateBus()
                   .Start(() => Configure.Instance.ForInstallationOn<Windows>().Install());

I think this will not disable the transaction and it's pretty similar to using the TransactionScope.Suppress() inside the handler.

Thanks & Best Regards,
Van

Andreas Ohlund

unread,
Oct 23, 2015, 7:12:12 AM10/23/15
to particula...@googlegroups.com
Hi Van!

You're correct in that disabling the handlers beeing wrapped in a scope is the same as TransactionScope.Suppress(). 

This essentially means that your bus.Send|Publish will not enlist in the receive transactions. This means that the messages will be sent out even if the receive transaction performs a rollback.

More on this here:


Does this make sense?

Cheers,

Andreas

--
You received this message because you are subscribed to the Google Groups "Particular Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to particularsoftw...@googlegroups.com.
To post to this group, send email to particula...@googlegroups.com.
Visit this group at http://groups.google.com/group/particularsoftware.
To view this discussion on the web visit https://groups.google.com/d/msgid/particularsoftware/108e6795-cc4a-4da1-80b1-4306278fd707%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Van Thi

unread,
Oct 24, 2015, 11:23:49 AM10/24/15
to Particular Software
Hi Andreas,
Thanks for your reply! So now I understand more on the impact of turning the setting DoNotWrapHandlersExecutionInATransactionScope while leaving the Transactions enabled by default.
From your link, it says: "This effectively turns the ambient transaction mode into transport transaction mode with regards to handler behavior".
Could you please explain what does the "transport transaction mode" here mean, or share me any links that explain it? Many thanks!

Best Regards,
Van
To unsubscribe from this group and stop receiving emails from it, send an email to particularsoftware+unsub...@googlegroups.com.

To post to this group, send email to particula...@googlegroups.com.
Visit this group at http://groups.google.com/group/particularsoftware.

Andreas Ohlund

unread,
Oct 26, 2015, 4:22:02 AM10/26/15
to particula...@googlegroups.com
>From your link, it says: "This effectively turns the ambient transaction mode into transport transaction mode with regards to handler behavior".
Could you please explain what does the "transport transaction mode" here mean, or share me any links that explain it?

By transport transaction we mean a native transaction supported by the transport that can include outgoing operations as well. The transports that currently have a "native" transaction is MSMQ and SqlServer. (Azure Service Bus have some limited support that we'll expose in the next version of our Azure ServiceBus transport)

In this case this didn't work as you expected due to our API being misleading, we're working on fixing this in the upcoming v6 release.

What happened for you is that you had MSMQ running in the default mode which uses a transaction scope to synchronize outgoing operations with the current receive operation. By suppressing the scope, you opted out of this behavior. While doing this, you still pay the price of distributed transactions since MSMQ will escalate to DTC even if no other resource manager is involved.

If you want to avoid DTC but still have your outgoing operations be consistent with the current receive operation you should use `.DisableDistributedTransactions` instead:


since that will cause MSMQ to use a native transaction instead.

Please accept our apologies for this confusing API and as mentioned above we're working on making it and the documentation more intuitive in the future.

Cheers,

Andreas
 

To unsubscribe from this group and stop receiving emails from it, send an email to particularsoftw...@googlegroups.com.
To post to this group, send email to particula...@googlegroups.com.
Visit this group at http://groups.google.com/group/particularsoftware.

--
You received this message because you are subscribed to the Google Groups "Particular Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to particularsoftw...@googlegroups.com.

To post to this group, send email to particula...@googlegroups.com.
Visit this group at http://groups.google.com/group/particularsoftware.

Van Thi

unread,
Oct 28, 2015, 11:31:38 AM10/28/15
to particula...@googlegroups.com
Hi Andreas,
Thanks for sharing more details. I'll need to read more and do some testing to fully understand this. My current need is to disable database transaction handling managed by NServiceBus so that I can control it by our code, while still keeps the transport transactional behavior such as: the message will be retried then moved to error queue if any error occurred; any Bus.Send() inside the handler will be roll backed. Is there any configuration to achieve that?
We've tried the option of disabling Distributed Transaction () then got the other exception.

It's great that you're working on simplifying those settings in the new version. While it's easy to configure it with a few line of code, it's complicated to fully understand how it work in case one of the setting is off.


Thanks & Best Regards,
Van


To unsubscribe from this group and stop receiving emails from it, send an email to particularsoftware+unsub...@googlegroups.com.
To post to this group, send email to particula...@googlegroups.com.
Visit this group at http://groups.google.com/group/particularsoftware.

--
You received this message because you are subscribed to the Google Groups "Particular Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to particularsoftware+unsub...@googlegroups.com.

To post to this group, send email to particula...@googlegroups.com.
Visit this group at http://groups.google.com/group/particularsoftware.

Andreas Ohlund

unread,
Nov 2, 2015, 6:12:09 AM11/2/15
to particula...@googlegroups.com
>We've tried the option of disabling Distributed Transaction () then got the other exception. 

I see now that you're on v4 and that version will still wrap your handlers in a transaction scope. Can you try to call both:

.DisableDistributedTransactions() and .
DoNotWrapHandlersExecutionInATransactionScope() 

since that should make sure that no transaction scope is in use.

v5 will do this by default for you when calling DisableDistributedTransactions()

Does this help?

Cheers,

Andreas

On Wed, Oct 28, 2015 at 4:31 PM, Van Thi <thitran...@gmail.com> wrote:
Hi Andreas,

Thanks for sharing more details. I'll need to read more and do some testing to fully understand this. My current need is to disable database transaction handling managed by NServiceBus so that I can control it by our code, while still keeps the transport transactional behavior such as: the message will be retried then moved to error queue if any error occurred; any Bus.Send() inside the handler will be roll backed. Is there any configuration to achieve that?
We've tried the option of disabling Distributed Transaction () then got the other exception.

It's great that you're working on simplifying those settings in the new version. While it's easy to configure it with a few line of code, it's complicated to fully understand how it work in case one of the setting is off.

Thanks & Best Regards,
Van

In my current code the Bus.Send() is executed as the last line inside the handler so I'm quite confident that there will not be a case that the message will be sent out twice, until I see the MSMQ dequeue exception.
To unsubscribe from this group and stop receiving emails from it, send an email to particularsoftw...@googlegroups.com.
To post to this group, send email to particula...@googlegroups.com.
Visit this group at http://groups.google.com/group/particularsoftware.

--
You received this message because you are subscribed to the Google Groups "Particular Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to particularsoftw...@googlegroups.com.

To post to this group, send email to particula...@googlegroups.com.
Visit this group at http://groups.google.com/group/particularsoftware.

--
You received this message because you are subscribed to the Google Groups "Particular Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to particularsoftw...@googlegroups.com.

To post to this group, send email to particula...@googlegroups.com.
Visit this group at http://groups.google.com/group/particularsoftware.
Reply all
Reply to author
Forward
0 new messages