Skip to content

Transaction context

Mogens Heller Grabe edited this page Sep 13, 2015 · 2 revisions

When Rebus receives messages, it does this by establishing a transaction context (something that implements ITransactionContext), which is then used throughout handling the message to perform actions in the right order.

It can be boiled down to wanting to support at least once delivery, which means that Rebus must never delete a message from a queue before it has been fully handled.

This can be achieved by always performing tasks in the right order:

  1. Receive message
  2. Do work(*)
  3. Delete message

and then just not perform step 3 if step 2 fails.

The transaction context helps you do that :)

How to use it

The first thing you can do, is to use the transaction context to stash things that you want to have access to thoughout your message handler and the logic that it carries out.

You will then usually set up your IoC container to resolve things by creating them on the first request, stashing them in the transcation context, and then resolving them from there on any subsequent requests within the same message handler.

The transcation context is capable of having actions enlisted in it, which will then be executed at the right time. You will probably use this mechanism to commit your work if it was successfully completed.

Accessing the transaction context

The transaction context is available everywhere it makes sense :)

If you're in a message handler, you can have an IMessageContext injected and use its TransactionContext property.

If you're in the [incoming messages pipeline|Incoming messages pipeline], you can use the [incoming step context|Incoming step context] to Load<ITransactionContext>().

Even if you don't have access to these things, you can still get to the transaction context via AmbientTransactionContext.Current, which is a logically thread-bound instance (i.e. it "flows" properly across continuations)

An example

If you're interested in seeing a full example on how the transaction context can be used to implement a proper unit of work, please check out the Unit of work page.

Clone this wiki locally