NHibernate command_timeout does not work with batches

JustAMartin picture JustAMartin · May 8, 2013 · Viewed 8.3k times · Source

Today I experienced an issue with timeouts.

I have the following configuration which is used to create a SessionFactory:

 <property name="adonet.batch_size">50</property>
 <property name="command_timeout">600</property>

I do not store it in web.config but in an XML file which is manually passed to the configuration:

configuration.Configure(cfgFile)

Thus I can have multiple session factories (per database) with independent configurations.

But the command_timeout seems to be effective only when NHibernate is not using batches. If SQL commands are batched then for some large batches I get:

NHibernate.Exceptions.GenericADOException: could not execute batch command.
[SQL: SQL not available] --->
System.Data.SqlClient.SqlException: Timeout expired. 
The timeout period elapsed prior to completion of the operation or the server is not responding.

While googling for a solution, I found an article which explains why this is happening: http://ronaldrosiernet.azurewebsites.net/Blog/2013/04/20/timeout_in_nhibernate_batched_sessions

The cause of the problem is that for SQL batching NHibernate is using Cfg.Environment.CommandTimeout instead of the command_timeout which is passed to a configuration when creating a session.

I found a way to implement a workaround when creating a Configuration:

if (configuration.Properties.ContainsKey(NHibernate.Cfg.Environment.CommandTimeout))
    NHibernate.Cfg.Environment.Properties[NHibernate.Cfg.Environment.CommandTimeout] = 
            configuration.Properties[NHibernate.Cfg.Environment.CommandTimeout];

and now my colleagues say that the timeout seems to be fixed now.

But what confuses me is the following thread: https://forum.hibernate.org/viewtopic.php?f=25&t=983105

which says:

The property NHibernate.Cfg.Environment.Properties returns you a copy of the global properties, so you cannot modify it.

If NHibernate.Cfg.Environment.Properties is a read-only copy, then why my workaround seems to be working fine? Is it stable or maybe this fix is unreliable and might break in some other cases?

And also I found a related issue in NHibernate JIRA: https://nhibernate.jira.com/browse/NH-2153

If they say they fixed issues with command_timeout in v3.1.0., then why do I still have to use my workaround in NHibernate v3.3.2. ?

Does anybody have any insight on this?

Answer

Manish Dalal picture Manish Dalal · Oct 18, 2013

I had same issue when using batches. Nhibernate class SqlClientBatchingBatcher using command timeout from Environment.GlobalProperties which is read only. I found only two ways to set timeout on SqlClientBatchingBatcher.currentBatch command

1) use timeout in app.config file

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

2) set Environment.

FieldInfo field = typeof(global::NHibernate.Cfg.Environment).GetField("GlobalProperties", System.Reflection.BindingFlags.NonPublic |                                     System.Reflection.BindingFlags.Static);
Dictionary<string, string> gloablProperties = field.GetValue(null) as Dictionary<string, string>;
gloablProperties.Add("command_timeout","120");