Changing NHibernate Session.Save command timeout
Asked Answered
F

1

13

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?

Frazzle answered 24/2, 2010 at 22:14 Comment(2)
It would be helpful if you posted a small sample app that reproduced the problem. Writing that small sample app may make it clear to you why it's not working.Fluoride
Great idea, but I did that already. I built a console app to replicate the problem, but the console app works and the web app does not.Frazzle
T
12

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 NHibernate 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 queries 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

Tabithatablature answered 25/2, 2010 at 7:36 Comment(7)
There are two different timeouts: 1) Connection Timeout 2) Command Timeout You are suggesting changing the 1st one, but I need to set the second. Read this for more details: tinyurl.com/ybpwkvlFrazzle
Have you tried the SetTimeout on the ICriteria Interface? which is probably what you are actually after.Tabithatablature
I am not sure I have access to ICriteria. I am trying to save the object through HibernateTemplate: HibernateTemplate.SaveOrUpdate(entity); HibernateTemplate.Flush();Frazzle
If you have the session object then you can create a criteria using Session.CreateCriteria. I will edit my answer to explain further.Tabithatablature
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?Frazzle
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.Tabithatablature
Have a look at springframework.net/doc-1.1-M1/sdk/1.1/html/… It may give you some ideasTabithatablature

© 2022 - 2024 — McMap. All rights reserved.