9

今天我遇到了超时问题。

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

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

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

configuration.Configure(cfgFile)

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

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.

在谷歌搜索解决方案时,我发现一篇文章解释了为什么会发生这种情况: 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];

现在我的同事说超时似乎现在已修复。

但让我感到困惑的是以下线程: 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 中使用我的解决方法。?

有人对此有任何见解吗?

4

1 回答 1

7

使用批处理时我遇到了同样的问题。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>

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");
于 2013-10-18T15:33:34.117 回答