views:

195

answers:

1

I am using NHibernate to connect to a legacy rdbms system. Under high production load the rdbms service fails. To maintain the availability we have a failover rdbms service. Is there a way to configure NHibernate to use the FailOver Connection String when the primary connection is down?

Additional Info: I am using Castle over NHibernate. If Castle provides handling of failover connections then that will also do it for me.

+2  A: 

You can build your own NHibernate.Connection.IConnectionProvider which provides failover support.

This should be a subclass of ConnectionProvider which overrides CloseConnection() GetConnection() and Configure().

The connection provider is specified in your hibernate configuration as property connection.provider.

Here is an untested implementation which is based on DriverConnectionProvider.

public class FailoverConnectionProvider : ConnectionProvider
{
    static string FailoverConnectionStringProperty = "connection.failover_connection_string";
    string failover_connstring;

    public override void CloseConnection(IDbConnection conn)
    {
        base.CloseConnection(conn);
        conn.Dispose();
    }

    public override IDbConnection GetConnection()
    {
        try {
            return GetConnection( ConnectionString );
        } catch {
            return GetConnection( failover_connstring );
        }
    }

    IDbConnection GetConnection( string connstring )
    {
        log.Debug("Obtaining IDbConnection from Driver");
        IDbConnection conn = Driver.CreateConnection();
        try {
            conn.ConnectionString = connstring;
            conn.Open();
        } catch (Exception) {
            conn.Dispose();
            throw;
        }

        return conn;
    }

    public override void Configure(IDictionary<string, string> settings)
    {
        base.Configure( settings );

        settings.TryGetValue(FailoverConnectionStringProperty, out failover_connstring);

        if (failover_connstring == null) {
            throw new HibernateException("Could not find connection string setting (set " + FailoverConnectionStringProperty + " property)");
        }
    }
}
Lachlan Roche
+1 How to specify NHibernate to then use this Custom ConnectionProvider?
Amitabh
@Lachlan: If we are using OpenSessionInView pattern in Asp.Net application then the OpenConnection request might come only once per request. If connection fails in between a request then this solution might not work.
Amitabh
A db exception during a session or transaction can easily put the session into an invalid state. In this situation, you could catch the error in page.OnError and use Server.Transfer to restart the request with a fresh session and connection.
Lachlan Roche
Do you have to add something extra to get NHibernate to naturally parse that custom property for the failover connection string? I've been having problems getting it to pass NHibernate's internal validation.
Brandon Linton