views:

1181

answers:

1

We have a couple of long running back-end processes that take longer than the default 30 seconds.

Our NHibernate version is 2.0.1.4000 and Spring.NET is 1.2.0.20313. NHibernate is configured through Spring.NET this way:

<object id="SessionFactory" type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate20">
    <property name="DbProvider" ref="DbProvider"/> 
    <property name="MappingAssemblies">
        <list>
            <value>SomeKindOfAnItem</value>
        </list> 
    </property>
    <property name="HibernateProperties">
        <dictionary>
            <entry key="expiration" value="120"/>
            <entry key="adonet.batch_size" value="10"/>
            <entry key="cache.provider_class" value="NHibernate.Caches.SysCache.SysCacheProvider, NHibernate.Caches.SysCache"/>
            <entry key="cache.use_query_cache" value="true"/>
            <entry key="connection.driver_class" value="NHibernate.Driver.SqlClientDriver"/>
            <entry key="connection.provider" value="NHibernate.Connection.DriverConnectionProvider"/>
            <entry key="dialect" value="NHibernate.Dialect.MsSql2005Dialect"/>
            <entry key="current_session_context_class" value="Spring.Data.NHibernate.SpringSessionContext, Spring.Data.NHibernate20"/>
            <entry key="show_sql" value="false"/>
        </dictionary>
    </property>
</object>

To get around this, I am trying to set the NHibernate command_timeout to 60 in the Web.config. This is from Web.config:

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory>
    <property name="command_timeout">60</property>
  </session-factory>
</hibernate-configuration>

Unfortunately this does not work, the command times out after 30 seconds.

I built a console app that calls the DAO just like the web app does it. I have the exact same NHibernate configuration setting in its configuration file. The IDbCommand times out after 60 seconds and not 30, using the setting successfully from the config file.

I tried debugging the app and check if the commandTimeout was set when the DAO assembly is called from the web site. It was.

This is from Visual Studio watch:

((NHibernate.Driver.DriverBase)(((NHibernate.Connection.DriverConnectionProvider) ((NHibernate.Impl.SessionFactoryImpl)session.SessionFactory) .ConnectionProvider).Driver)).commandTimeout: 60

The session is created like this:

ISession session = SessionFactoryUtils.GetSession(HibernateTemplate.SessionFactory, true);

My question is: if the command timeout field was successfully set to 60 from my Web.config, why does it time out after 30 seconds? Any ideas I could try?

+1  A: 

You could set the timeout as part of the hibernate.connection.connection_string property. I haven't used Spring.Net so I am not sure how it sets up the nhibinate session factory. if you are able to add "Connect Timeout=120" to the connection string. This should increase the time from the default 30 second timeout to 120 seconds. The following line would go in the web config

<property name="connection.connection_string">Server=localhost;initial catalog=nhibernate;User Id=;Password=; Connect Timeout=120;</property>

EDIT
It turns out that there are actually two timeouts. Thanks to adomokos for pointing that out. One for the actual opening of the connection and another for the quieries that are executed.

The one for the connection is displayed above, however to set the timeout for a query with nhibernate you use the ICriteria interface.

ICriteria crit = session.CreateCriteria(typeof(Foo)); 
crit.SetTimeout(120); 
List<Foo> fooList = crit.List();

The timeout value is in seconds.

Hope that helps

Nathan Fisher
There are two different timeouts:1) Connection Timeout2) Command TimeoutYou are suggesting changing the 1st one, but I need to set the second. Read this for more details: http://tinyurl.com/ybpwkvl
adomokos
Doh.. You are correct. I picked the wrong one
Nathan Fisher
Have you tried the SetTimeout on the ICriteria Interface? which is probably what you are actually after.
Nathan Fisher
I am not sure I have access to ICriteria. I am trying to save the object through HibernateTemplate: HibernateTemplate.SaveOrUpdate(entity); HibernateTemplate.Flush();
adomokos
If you have the session object then you can create a criteria using Session.CreateCriteria. I will edit my answer to explain further.
Nathan Fisher
Thanks Nate for helping me out! Your code sample would work if I needed to pull data from the data store, however, I get timeout when I try to save the object: "HibernateTemplate.SaveOrUpdate(entity);" How could you set the the timeout on the HibernateTemplate?
adomokos
Ok so this has more to Saving data rather that retrieveing data. Most of the information regarding timeouts I have found has to do with retrieveing data. There is the SessionFactoryUtils.ApplyTransactionTimeout() method but that requires a sessionfactory and an IQuery or ICriteria. There must be a lot going on for a save to last more that 30 seconds.
Nathan Fisher
Have a look at http://www.springframework.net/doc-1.1-M1/sdk/1.1/html/Spring.Data.NHibernate~Spring.Data.NHibernate.HibernateTransactionManager.html It may give you some ideas
Nathan Fisher