2013-05-08 8 views
8

Heute hatte ich ein Problem mit Timeouts.NHibernate command_timeout funktioniert nicht mit Batches

Ich habe die folgende Konfiguration, die eine Session erstellen verwendet wird:

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

in web.config es ich nicht speichern, sondern in einer XML-Datei, die manuell in die Konfigurationsübergeben wird:

configuration.Configure(cfgFile) 

So kann ich mehrere Sitzungsfabriken (pro Datenbank) mit unabhängigen Konfigurationen haben.

Die command_timeout scheint jedoch nur wirksam zu sein, wenn NHibernate keine Stapel verwendet. Wenn SQL-Befehle dann für einige große Chargen chargiert werden erhalte ich:

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. 

Während für eine Lösung googeln, fand ich einen Artikel, der erklärt, warum dies geschieht: http://ronaldrosiernet.azurewebsites.net/Blog/2013/04/20/timeout_in_nhibernate_batched_sessions

Die Ursache des Problems ist, dass Für das SQL-Batching verwendet NHibernate Cfg.Environment.CommandTimeout anstelle von command_timeout, das beim Erstellen einer Sitzung an eine Konfiguration übergeben wird.

fand ich einen Weg, um eine Problemumgehung zu implementieren, wenn eine Konfiguration zu erstellen:

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

und jetzt meine Kollegen sagen, dass das Timeout festgelegt zu sein scheint.

Aber was mich verwirrt, ist das folgende Thema: https://forum.hibernate.org/viewtopic.php?f=25&t=983105

die sagt:

Die Eigenschaft NHibernate.Cfg.Environment.Properties Sie liefert eine Kopie der globalen Eigenschaften, so dass Sie nicht modifiziere es.

Wenn NHibernate.Cfg.Environment.Properties eine schreibgeschützte Kopie ist, warum dann scheint meine Abhilfe zu funktionieren? Ist es stabil oder ist diese Korrektur unzuverlässig und könnte in anderen Fällen auftreten?

Und ich fand auch ein ähnliches Problem in NHibernate JIRA. https://nhibernate.jira.com/browse/NH-2153

Wenn sie sagen, dass sie Probleme behoben mit command_timeout in v3.1.0, warum muss ich immer noch meine Abhilfe in NHibernate V3.3.2 verwenden . ?

Hat jemand irgendeinen Einblick darauf?

Antwort

5

Ich hatte das gleiche Problem bei der Verwendung von Chargen. Nhibernate-Klasse SqlClientBatchingBatcher mit Befehlszeitüberschreitung von Environment.GlobalProperties, die schreibgeschützt ist. Ich fand nur zwei Möglichkeiten Timeout auf SqlClientBatchingBatcher.currentBatch Befehl

1) Verwenden Timeout in app.config Datei

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

2) eingestellt Umgebung festzulegen.

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

Ich würde 'global :: NHibernate.Cfg.Environment.CommandTimeout'-Eigenschaft anstelle der String-Konstante' "command_timeout" 'hier verwenden. – Alex

Verwandte Themen