![]() |
VOOZH | about |
dotnet add package Rebus.SqlServer --version 8.4.1
NuGet\Install-Package Rebus.SqlServer -Version 8.4.1
<PackageReference Include="Rebus.SqlServer" Version="8.4.1" />
<PackageVersion Include="Rebus.SqlServer" Version="8.4.1" />Directory.Packages.props
<PackageReference Include="Rebus.SqlServer" />Project file
paket add Rebus.SqlServer --version 8.4.1
#r "nuget: Rebus.SqlServer, 8.4.1"
#:package Rebus.SqlServer@8.4.1
#addin nuget:?package=Rebus.SqlServer&version=8.4.1Install as a Cake Addin
#tool nuget:?package=Rebus.SqlServer&version=8.4.1Install as a Cake Tool
Provides Microsoft SQL Server implementations for Rebus for
👁 alternate text is missing from this package README image
Rebus' SQL package requires at least Microsoft SQL Server 2008.
Microsoft SQL Server is a relational database and not a queueing system.
While it does provide the necessary mechanisms to implement queues, it's not optimized for the type of operations required to implement high-performance queues.
Therefore, please only use the SQL transport if your requirements are fairly modest (and what that means in practice probably depends a lot on the hardware available to you).
The Rebus configuration spell goes either
services.AddRebus(configure => configure.(...));
or
Configure.With(...)
.(...)
.Start();
depending on whether you're using Microsoft DI or some other IoC container.
The following configuration examples will use the Microsoft DI-style of configuration, but the use of Rebus' configuration extensions is the same regardless of which type of configuration you are using, so it should be fairly easy to convert to the style you need.
Rebus only really requires one part of its configuration: A configuration of the "transport" (i.e. which queueing system, you're going to use).
The SQL transport is not recommended for heavier workloads, but it can be fine in cases where you do not require a super-high throughput. Here's how to configure it
(in this case using the name queue-name as the name of the instance's input queue):
services.AddRebus(
configure => configure
.Transport(t => t.UseSqlServer(connectionString, "queue-name"))
);
To configure Rebus to store sagas in SQL Server, you can do it like this (using the table 'Sagas' for the saga data, and 'SagaIndex' for the corresponding correlation properties):
services.AddRebus(
configure => configure
.(...)
.Sagas(t => t.StoreInSqlServer(connectionString, "Sagas", "SagaIndex"))
);
To configure Rebus to store subscriptions in SQL Server, you can do it like this (using the table 'Subscriptions'):
services.AddRebus(
configure => configure
.(...)
.Subscriptions(t => t.StoreInSqlServer(connectionString, "Subscriptions", isCentralized: true))
);
Please note the use of isCentralized: true – it indicates that the subscription storage is "centralized", meaning that both subscribers and publishers use the same storage.
If you use the isCentralized: false option, then subscribers need to know the queue names of the publishers of the events they want to subscribe to, and then they will subscribe by sending a message to the publisher.
Using isCentralized: true makes the most sense in most scenarios, as it's easier to work with.
If you're using a transport that does not natively support "timeouts" (also known as "deferred messages", or "messages sent into the future" 🙂), you can configure one of your Rebus instances to function as a "timeout manager". The timeout manager must have some kind of timeout storage configured, and you can use SQL Server to do that.
You configure it like this (here using RabbitMQ as the transport):
services.AddRebus(
configure => configure
.Transport(t => t.UseRabbitMq(connectionString, "timeout_manager"))
.Timeouts(t => t.StoreInSqlServer(connectionString, "Timeouts"))
);
In most cases, it can be super nice to simply configure one single timeout manager with a globally known queue name (e.g. "timeout_manager") and then make use of it from all other Rebus instances by configuring them to use the timeout manager for deferred messages:
services.AddRebus(
configure => configure
.Transport(t => t.UseRabbitMq(connectionString, "another-eueue"))
.Timeouts(t => t.UseExternalTimeoutManager("timeout_manager"))
);
This will cause someMessage to be sent to the timeout manager when you await bus.Defer(TimeSpan.FromMinutes(5), someMessage), which will store it in its timeouts database for 5 minutes before sending it to whoever was configured as the recipient of someMessage.
The transactional outbox in Rebus.SqlServer ensures consistent and reliable message delivery by storing outgoing messages in an outbox table within the same SQL transaction as your other database operations. This approach helps prevent data inconsistencies in case of failures, as it ties the message dispatch to the success of your data changes.
To configure the transactional outbox with Rebus, use the Outbox extension method during the setup. Rebus allows you to use any transport, and the outbox will work in conjunction with your chosen transport.
services.AddRebus(
configure => configure
.Transport(t => /* configure your transport here */)
.Outbox(o => o.StoreInSqlServer(connectionString, "Outbox"))
);
connectionString: The connection string to your SQL Server database."Outbox": The name of the table where outbox messages will be stored.When you are outside a Rebus handler (e.g., in a web request or any other application context), you need to manage the SQL connection and transaction manually. Here's how you can do it:
using var connection = new SqlConnection(connectionString);
await connection.OpenAsync();
using var transaction = connection.BeginTransaction();
try
{
using var scope = new RebusTransactionScope();
scope.UseOutbox(connection, transaction);
// Perform your database operations using 'connection' and 'transaction'
// Send messages using Rebus
await bus.Send(new YourMessage());
// Complete the Rebus transaction scope
await scope.CompleteAsync();
// Commit your transaction
await transaction.CommitAsync();
}
catch (Exception ex)
{
// Handle exceptions
await transaction.RollbackAsync();
// Log or rethrow the exception as needed
}
SqlConnection and begin a SqlTransaction.scope.UseOutbox(connection, transaction) to inform Rebus to use your connection and transaction.scope.CompleteAsync(), commit the transaction to ensure both your data changes and messages are persisted atomically.When inside a Rebus handler, Rebus manages the SQL connection and transaction for you. To include your database operations in the same transaction as Rebus, you can access the connection and transaction from the message context.
public class YourMessageHandler : IHandleMessages<YourMessage>
{
public async Task Handle(YourMessage message)
{
var messageContext = MessageContext.Current
?? throw new InvalidOperationException("No message context available.");
var transactionContext = messageContext.TransactionContext;
var outboxConnection = (OutboxConnection)transactionContext.Items["current-outbox-connection"];
var connection = outboxConnection.SqlConnection;
var transaction = outboxConnection.SqlTransaction;
// Perform your database operations using 'connection' and 'transaction'
// Send messages using Rebus; they will be included in the same transaction
await messageContext.Bus.Send(new AnotherMessage());
}
}
MessageContext.OutboxConnection from the transaction context.outboxConnection.SqlConnection and outboxConnection.SqlTransaction to perform your database operations.Once a message is stored in the outbox table and the transaction is committed, Rebus handles the retrieval and forwarding of the message to its intended destination. This ensures that message dispatch is reliable and decoupled from your application logic.
For practical examples of how to implement the transactional outbox with Rebus.SqlServer, you can refer to the following sample projects in the GitHub repository:
These examples demonstrate the outbox implementation in different contexts, including integration with Entity Framework Core.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 net5.0 was computed. net5.0-windows net5.0-windows was computed. net6.0 net6.0 was computed. net6.0-android net6.0-android was computed. net6.0-ios net6.0-ios was computed. net6.0-maccatalyst net6.0-maccatalyst was computed. net6.0-macos net6.0-macos was computed. net6.0-tvos net6.0-tvos was computed. net6.0-windows net6.0-windows was computed. net7.0 net7.0 was computed. net7.0-android net7.0-android was computed. net7.0-ios net7.0-ios was computed. net7.0-maccatalyst net7.0-maccatalyst was computed. net7.0-macos net7.0-macos was computed. net7.0-tvos net7.0-tvos was computed. net7.0-windows net7.0-windows was computed. net8.0 net8.0 was computed. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 was computed. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 was computed. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 netcoreapp2.0 was computed. netcoreapp2.1 netcoreapp2.1 was computed. netcoreapp2.2 netcoreapp2.2 was computed. netcoreapp3.0 netcoreapp3.0 was computed. netcoreapp3.1 netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 netstandard2.0 is compatible. netstandard2.1 netstandard2.1 was computed. |
| .NET Framework | net461 net461 was computed. net462 net462 was computed. net463 net463 was computed. net47 net47 was computed. net471 net471 was computed. net472 net472 was computed. net48 net48 was computed. net481 net481 was computed. |
| MonoAndroid | monoandroid monoandroid was computed. |
| MonoMac | monomac monomac was computed. |
| MonoTouch | monotouch monotouch was computed. |
| Tizen | tizen40 tizen40 was computed. tizen60 tizen60 was computed. |
| Xamarin.iOS | xamarinios xamarinios was computed. |
| Xamarin.Mac | xamarinmac xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos xamarinwatchos was computed. |
Showing the top 5 NuGet packages that depend on Rebus.SqlServer:
| Package | Downloads |
|---|---|
|
Ark.Tools.Rebus
NLog configuration helper and extensions for Ark standard configuration using code and not config files. |
|
|
Ark.Tools.Activity
Event based Activity based on time-slices with dependencies |
|
|
Ark.Tools.EventSourcing.Rebus
EventSourcing Rebus integration |
|
|
Ark.Tools.Outbox.Rebus
Outbox pattern implementation |
|
|
EventSub
Event Grid/Eventbridge style service that will store messages and forward to a subscriber URL |
Showing the top 4 popular GitHub repositories that depend on Rebus.SqlServer:
| Repository | Stars |
|---|---|
|
CodeMazeBlog/CodeMazeGuides
The main repository for all the Code Maze guides
|
|
|
DataDog/dd-trace-dotnet
.NET Client Library for Datadog APM
|
|
|
mastreeno/Merp
An event based Micro ERP
|
|
|
rebus-org/RebusSamples
Small sample projects
|
| Version | Downloads | Last Updated |
|---|---|---|
| 8.4.1 | 165,270 | 2/14/2026 |
| 8.4.0 | 176,122 | 11/8/2025 |
| 8.4.0-b01 | 125,007 | 3/21/2025 |
| 8.3.0 | 1,931,874 | 1/28/2025 |
| 8.2.0 | 108,032 | 12/16/2024 |
| 8.1.2 | 1,826,115 | 4/11/2024 |
| 8.1.1 | 257,929 | 2/7/2024 |
| 8.1.0 | 4,956 | 2/7/2024 |
| 8.0.3 | 22,138 | 2/7/2024 |
| 8.0.2 | 214,973 | 11/21/2023 |
| 8.0.1 | 14,198 | 11/21/2023 |
| 8.0.0 | 19,619 | 11/15/2023 |
| 8.0.0-alpha02 | 827 | 4/6/2023 |
| 7.3.1 | 346,671 | 2/6/2023 |
| 7.3.0 | 51,512 | 1/27/2023 |
| 7.3.0-b5 | 2,921 | 10/28/2022 |
| 7.3.0-b4 | 796 | 8/2/2022 |
| 7.3.0-b3 | 1,673 | 5/6/2022 |
| 7.3.0-b2 | 727 | 5/6/2022 |
| 7.3.0-b1 | 722 | 5/5/2022 |