【问题标题】:NHibernate command_timeout does not work with batchesNHibernate command_timeout 不适用于批处理
【发布时间】:2013-05-02 23:21:21
【问题描述】:

今天我遇到了超时问题。

我有以下用于创建 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 中使用我的解决方法。 ?

有人对此有任何见解吗?

【问题讨论】:

    标签: nhibernate timeout batch-processing


    【解决方案1】:

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

    【讨论】:

    • 我会在这里使用global::NHibernate.Cfg.Environment.CommandTimeout 属性而不是字符串常量"command_timeout"
    猜你喜欢
    • 1970-01-01
    • 2013-12-15
    • 1970-01-01
    • 2012-05-02
    • 1970-01-01
    • 2021-11-28
    • 2021-11-26
    • 2012-06-17
    • 1970-01-01
    相关资源
    最近更新 更多