NServiceBus - Problem with using TransactionScopeOption.Suppress in message handler

情到浓时终转凉″ 提交于 2019-12-13 19:10:14

问题


I have an endpoint that has a message handler which does some FTP work. Since the ftp process can take some time, I encapsulated the ftp method within a TransactionScope with TransactionScopeOption.Suppress to prevent the transaction timeout exceptions.

Doing this got rid of the timeout exceptions, however the handler was fired 5 times (retries is set to 5 in my config file)

The files were ftp'd ok, but they were just ftp'd 5 times.

the handler look like it is re-fired after 10 or 11 minutes.

some test code looks as follows:

public void Handle(FtpMessage msg)
{
     using (TransactionScope t = new TransactionScope(TransactionScopeOption.Suppress))
     {
          FtpFile(msg);
     }
}

Any help would be greatly appreciated.

thanks.


回答1:


My guess is that by not completing the inner scope you're causing the outer scope, created by NSB, to rollback. This will cause NSB to retry your FtpMessage.

Try to add: t.Complete(); after your call to FtpFile and see if that does it for you.

Edit: After rereading your question I realized that this won't solve your timeout issue. Have you tried to increase the timeout? (10 min is the default maxValue in machine.config so you can't set it to higher without modifying machine.config)




回答2:


If this truly is an FTP communication that cannot be completed within the transaction timeout, another approach would be to turn this into a Saga.

The Saga would be started by FtpMessage, and in the handler it would start the FTP work asynchronously, whether in another thread, or via another process, or whatever, and store enough information in saga data to be able to look up the progress later.

Then it would request a timeout from the TimeoutManager for however long makes sense. Upon receiving that timeout, it would look up the state in saga data, and check on the FTP work in progress. If it's completed, mark the saga as complete, if not, request another timeout.

Alternatively, you could have a process wrapping the FTP communication that hosts its own Bus but does not have any message handlers of its own. It could receive its FTP information via the command line (including requesting endpoint), do its work, and then send a message back to the requesting endpoint saying it is complete. Then you would not have to wait for a timeout to move on with the process.




回答3:


I'd recommend configuring that endpoint as non-transactional rather than trying to suppress the transaction. Do that by including .IsTransactional(false) in your initialization code if self-hosting or by implementing IConfigureThisEndpoint, AsA_Client when using the generic host.



来源:https://stackoverflow.com/questions/3702178/nservicebus-problem-with-using-transactionscopeoption-suppress-in-message-hand

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!