Multi-Instance Mode

Component: SQL Server Transport
NuGet Package NServiceBus.SqlServer (2.x)
Target NServiceBus Version: 5.x
In Version 4 the multi-instance mode has been deprecated. The migration sample explains how to use the Transport Bridge instead.


An instance of SQL Server Express is installed and accessible as .\SqlExpress.

At startup each endpoint will create its required SQL assets including databases, tables and schemas.

The databases created by this sample are NsbSamplesSqlMultiInstanceReceiver and NsbSamplesSqlMultiInstanceSender.

Ensure Distributed Transaction Coordinator (DTC) is running. It can be started from the command line by running net start msdtc.

Running the project

  1. Start both projects.
  2. Hit enter in Sender's console window to send a new message.

Verifying that the sample works correctly

  1. The Receiver displays information that an order was submitted.
  2. The Sender displays information that the order was accepted.

Code walk-through

This sample contains the following projects:

  • Sender - A console application responsible for sending the initial ClientOrder message and processing the follow-up ClientOrderAccepted message.
  • Receiver - A console application responsible for processing the order message.
  • Messages - A class library containing message definitions.
In Versions 2 and below it is required to pass connection string for the currently configured endpoint either using ConnectionString() method or in the app.config file.

Sender project

The Sender does not store any data. It mimics the front-end system where orders are submitted by the users and passed via the bus to the back-end. It is configured to use SQL Server transport and run in the multi-instance mode. ConnectionProvider.GetConnection method is used for providing connections.

var busConfiguration = new BusConfiguration();
var transport = busConfiguration.UseTransport<SqlServerTransport>();

The Sender sends a message to the Receiver:

var order = new ClientOrder
    OrderId = Guid.NewGuid()
bus.Send("Samples.SqlServer.MultiInstanceReceiver", order);

Receiver project

The Receiver mimics a back-end system. It is configured to use SQLServer transport in the multi-instance mode.

var busConfiguration = new BusConfiguration();
var transport = busConfiguration.UseTransport<SqlServerTransport>();

It receives ClientOrder message sent by Sender and replies to them with ClientOrderAccepted.

public void Handle(ClientOrder message)
    log.Info($"Handling ClientOrder with ID {message.OrderId}");
    var clientOrderAccepted = new ClientOrderAccepted
        OrderId = message.OrderId

Multi-instance connection lookup

Both sender and receiver provide a custom lookup mechanism for providing connection information for given destination. The following snippet shows lookup logic used by Sender.

static class ConnectionInfoProvider
    const string ReceiverConnectionString = @"Data Source=.\SqlExpress;Database=NsbSamplesSqlMultiInstanceReceiver;Integrated Security=True";
    public const string DefaultConnectionString = @"Data Source=.\SqlExpress;Database=NsbSamplesSqlMultiInstanceSender;Integrated Security=True";

    public static ConnectionInfo GetConnection(string transportAddress)
        string connectionString;
        if (transportAddress.StartsWith("Samples.SqlServer.MultiInstanceReceiver"))
            connectionString = ReceiverConnectionString;
            connectionString = DefaultConnectionString;

        return ConnectionInfo

How it works

Sender and Receiver use different catalogs on the same SQL Server instance. The tables representing queues for a particular endpoint are created in the appropriate catalog, i.e. in NsbSamplesSqlMultiInstanceReceiver for the Receiver endpoint and in NsbSamplesSqlMultiInstanceSender for the Sender endpoint. It is possible to register a custom SqlConnection factory that provides connection instance per given transport address. The operations performed on queues stored in different catalogs are atomic because SQL Server allows multiple SqlConnection enlisting in a single distributed transaction.

In this sample DTC is required by the Receiver because it operates on two different catalogs when receiving Sender's request. It picks message from input queue stored in NsbSamplesSqlMultiInstanceReceiver and sends back reply to Sender's input queue stored in NsbSamplesSqlMultiInstanceSender. In addition error queue is stored also in NsbSamplesSqlMultiInstanceSender so without DTC Receiver will not be able handle failed messages properly.

Related Articles

Last modified