0
votes

I'm new to nServiceBus.

If the bus is configured with IsTransactional(true) and the handler has a lot of db interaction, the asp.net mvc application hangs up.

Here - http://adamfyles.blogspot.com/2010/08/getting-started-with-nservicebus-part-2_25.html - I found a tip: "IsTransactional(false) - we don't want to hang a web app up in transactions, so turn this off"

And it helped - the page is refreshing quickly. On the other side, if an exception happens, the msmq queue is lost.

Let me explain what the handler does - it iterates over some db rows, generates a report and updates the 'ReportId' key on that record:

foreach(var row in rows)
{
  var reportId = GenerateReport(row);

  row.ReportId = reportId;
}

db.Save();

As I said, I'm new to nServiceBus. Do I have to use Saga for this? I don't understand saga's yet. Or maybe I can do something like this:

foreach(var row in rows)
{
   _bus.Send(new GenerateReportMessage{Id = row.Id});
}    

And let the handler generate the report and update the row? How will I know that all records were updated? Will the web app hang up too with 'IsTransactional(true)' in this case? (I suspect that yes)

My questions:

  1. What should I be aware of when I'm using 'IsTransactional(false)'?

  2. What is best way to update a lot of records? Just update them in the loop? And I don't want the web app to hang.

EDIT

Btw, this code seems to not hang the web app, and it works with IsTransactional(true).

Is this a good approach?

using (new TransactionScope(TransactionScopeOption.Suppress))
{

    foreach(var row in rows.Where(x => x.ReportId != null))
    {
    var reportId = GenerateReport(row);

    row.ReportId = reportId;
    }

    db.Save();    
}
1
Off topic but Udi Dahan did a talk on dnrTV about NServiceBus - dnrtv.com/default.aspx?showNum=199Phill

1 Answers

0
votes

You are correct that you may lose messages with IsTransactional(false). The trade off is that you don't include the web application in the transactional boundary. Including it may slow your web app down as it waits for acks back from the server side. I would suggest either forwarding the message to another endpoint to do the work that is transactional or exposing a transactional endpoint using the built-in WCF integration. If you go the WCF route, just remember you can't return anything from the service other than an error code. It also uses the basicHttpBinding out of the box but you can change that if you so desire.