9

今日、タイムアウトの問題が発生しました。

SessionFactory の作成に使用される次の構成があります。

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

私はそれを web.config には保存しませんが、構成に手動で渡される XML ファイルに保存します。

configuration.Configure(cfgFile)

したがって、独立した構成を持つ複数のセッション ファクトリを (データベースごとに) 持つことができます。

しかし、command_timeoutNHibernate がバッチを使用していない場合にのみ効果があるようです。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

command_timeoutこの問題の原因は、SQL バッチ処理で、セッションの作成時に構成に渡される の代わりに、NHibernate が Cfg.Environment.CommandTimeout を使用していることです。

構成を作成するときに回避策を実装する方法を見つけました。

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 コマンドでタイムアウトを設定する方法が 2 つしか見つかりませんでした

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 に答える