I was to make Rhino Service Bus work with NHibernate the other day. Although, Nhibernate and Rhino Service Bus each work flawlessly, when coupled together the problem started. What I wanted to do was simple. Gather some orders to make a package large enough for shipment gateway to process.

As soon as I hit the database to check if I have enough orders to create a shipment package, strange errors occurred. What I did when a new order is received was this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class ShipmentSaga : ConsumerOf<NewOrderMessage>
{
public const int PackageLimit = 5;

public ShipmentSaga(IServiceBus bus)
{
this.Bus = bus;
}

public IServiceBus Bus
{
get;
private set;
}

public void Consume(NewOrderMessage orderMessage)
{
var packagefull = HasEnoughOrders();
if (packagefull)
{
var message = new PrepareShipmentMessage();
Bus.Send(message);
}
}

private bool HasEnoughOrders()
{
using(var session = IoC.Resolve<ISessionFactory>().OpenSession())
{
var todayOrders = session.CreateCriteria(typeof(Order))
.Add(Expression.Eq("OrderDate", DateTime.Now.Date))
.Add(Expression.Eq("IsShipped", false))
.List<Order>();

return todayOrders.Count >= PackageLimit;
}
}
}

As soon as the execution of HasEnoughOrders finished and system tried to dispose and close the session, an exception occurred saying : “Disconnect cannot be called while a transaction is in progress”. Ayende says this is the problem of NHibernate handling TransactionScopes. NH registers the session for DTC transactions but it does not defer the transaction’s disposal the way it should. Hopefully the bug will be fixed in future releases of NH and there is a workaround. To “temporarily” avoid this problem, do not explicitly dispose the session:

1
2
3
4
5
6
7
8
9
10
11
private bool HasEnoughOrders()
{
var session = IoC.Resolve<ISessionFactory>().OpenSession();

var todayOrders = session.CreateCriteria(typeof(Order))
.Add(Expression.Eq("OrderDate", DateTime.Now.Date))
.Add(Expression.Eq("IsShipped", false))
.List<Order>();

return todayOrders.Count >= PackageLimit;
}

Rhino Service Bus is still under development so there might be other minor issues when used together with other technologies and frameworks, but it is a great piece of software. If you’re not familiar with Rhino Tool set, you definitely need to take a look. Thank you Ayende for creating such a great toolkit.