Monday, December 29, 2008

NH + Rhino ESB = Headache?

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 :

ESB-Ordering-Workflow

As soon as I hit the database to check if I have enough orders to create a shipment package, strange errors occured. Here’s what I did when a new order is recieved :

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 occured 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 :



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.


Submit this story to DotNetKicks Shout it

2 comments:

Ayende Rahien said...

I am definitely going to fix this issue.

Ayende Rahien said...

this should be fixed now