2013-05-08 47 views
8

今天我遇到了超時的問題。NHibernate的command_timeout不適用於批處理

我有以下的配置,用來創建一個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 。 ?

有沒有人對此有所瞭解?

回答

5

我在使用批次時遇到同樣的問題。 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"); 
+0

我會在這裏使用'global :: NHibernate.Cfg.Environment.CommandTimeout'屬性代替字符串常量'「command_timeout」'。 – Alex 2014-08-07 14:27:23

相關問題