2013-05-08 12 views
8

Dzisiaj napotkałem problem z przekroczeniem limitów czasu.NHibernate command_timeout nie działa z partiami

mam następującą konfigurację, która służy do tworzenia SessionFactory:

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

nie przechowywać go w pliku web.config, ale w pliku XML, który jest ręcznie przekazany do konfiguracji:

configuration.Configure(cfgFile) 

Dzięki temu mogę mieć wiele fabryk sesji (na bazę danych) z niezależnymi konfiguracjami.

Ale command_timeout wydaje się być skuteczne tylko wtedy, gdy NHibernate nie używa partii. Jeśli polecenia SQL są grupowane następnie dla niektórych dużych partiach uzyskać:

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. 

Podczas googlowania rozwiązania, znalazłem artykuł, który wyjaśnia, dlaczego tak się dzieje: http://ronaldrosiernet.azurewebsites.net/Blog/2013/04/20/timeout_in_nhibernate_batched_sessions

Przyczyną problemu jest to, że dla grupowania SQL NHibernate używa Cfg.Environment.CommandTimeout zamiast command_timeout, który jest przekazywany do konfiguracji podczas tworzenia sesji.

znalazłem sposób aby zaimplementować obejście podczas tworzenia konfiguracji:

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

i teraz moi koledzy mówią, że limit czasu wydaje się być naprawione.

Ale co mnie niepokoi to wątku: https://forum.hibernate.org/viewtopic.php?f=25&t=983105

który mówi:

W NHibernate.Cfg.Environment.Properties właściwość zwraca ci kopię właściwości globalne, więc nie można zmodyfikuj to.

Jeśli NHibernate.Cfg.Environment.Properties jest kopią tylko do odczytu, dlaczego moje obejście działa poprawnie? Czy jest stabilny, czy może ta poprawka jest niewiarygodna i może popsuć się w innych przypadkach?

A także znalazłem podobnych problemów w NHibernate JIRA. https://nhibernate.jira.com/browse/NH-2153

Jeśli mówią, że stałe problemy z command_timeout w v3.1.0, to dlaczego wciąż muszę używać mojego obejścia w NHibernate v3.3.2 . ?

Czy ktoś ma wgląd w to?

Odpowiedz

5

Miałem ten sam problem podczas korzystania z partii. Nhibernate klasy SqlClientBatchingBatcher za pomocą timeout polecenia z Environment.GlobalProperties, który jest tylko do odczytu. Znalazłem tylko dwa sposoby, aby ustawić czas oczekiwania na komendę SqlClientBatchingBatcher.currentBatch

1) Użyj limitu czasu w pliku app.config

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

2) Ustaw środowisko.

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

Użyłbym właściwości 'global :: NHibernate.Cfg.Environment.CommandTimeout' zamiast stałej łańcuchowej' "command_timeout" 'tutaj. – Alex