NHibernate command_timeout不适用于批处理

Jus*_*tin 8 nhibernate timeout batch-processing

今天我遇到了超时问题.

我有以下配置用于创建SessionFactory:

 <property name="adonet.batch_size">50</property>
 <property name="command_timeout">600</property>
Run Code Online (Sandbox Code Playgroud)

我不将它存储在web.config中,而是存储在手动传递给配置的XML文件中:

configuration.Configure(cfgFile)
Run Code Online (Sandbox Code Playgroud)

因此,我可以拥有多个具有独立配置的会话工厂(每个数据库).

但是,command_timeout只有当NHibernate不使用批次时,这似乎才有效.如果SQL命令是批处理的,那么对于一些大批量我得到:

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.
Run Code Online (Sandbox Code Playgroud)

在谷歌搜索解决方案时,我发现了一篇文章,解释了为什么会发生这种情况:http: //ronaldrosiernet.azurewebsites.net/Blog/2013/04/20/timeout_in_nhibernate_batched_sessions

问题的原因是,对于SQL批处理,NHibernate使用Cfg.Environment.CommandTimeout而不是command_timeout在创建会话时传递给配置.

我找到了一种在创建配置时实现变通方法的方法:

if (configuration.Properties.ContainsKey(NHibernate.Cfg.Environment.CommandTimeout))
    NHibernate.Cfg.Environment.Properties[NHibernate.Cfg.Environment.CommandTimeout] = 
            configuration.Properties[NHibernate.Cfg.Environment.CommandTimeout];
Run Code Online (Sandbox Code Playgroud)

现在我的同事们说暂停现在似乎已经解决了.

但令我困惑的是以下主题:https://forum.hibernate.org/viewtopic.php?f = 25& t = 983105

其中说:

NHibernate.Cfg.Environment.Properties属性返回全局属性的副本,因此您无法对其进行修改.

如果NHibernate.Cfg.Environment.Properties是一个只读副本,那么为什么我的解决方法似乎工作正常?它是稳定的还是这个修复程序不可靠并且在其他一些情况下可能会中断?

此外,我在NHibernate JIRA中发现了一个相关问题:https: //nhibernate.jira.com/browse/NH-2153

如果他们说他们在v3.1.0中修复了command_timeout的问题,那么为什么我仍然需要在NHibernate v3.3.2中使用我的解决方法.?

有没有人对此有任何见解?

小智 6

使用批次时我遇到了同样的问题.Nhibernate类SqlClientBatchingBatcher使用来自Environment.GlobalProperties的命令超时,它是只读的.我发现只有两种方法可以在SqlClientBatchingBatcher.currentBatch命令上设置超时

1)在app.config文件中使用超时

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory>
    <property name="command_timeout">120</property>
  </session-factory>
</hibernate-configuration>
Run Code Online (Sandbox Code Playgroud)

2)设置环境.

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");
Run Code Online (Sandbox Code Playgroud)