2009-08-13 6 views
2

Subsonic ActiveRecordとSql Serverを使用して新しいレコードをすばやく追加すると、タイムアウトSqlExceptionが発生します。Subsonic ActiveRecord - たくさんのレコードを追加するときにハングする接続

タイムアウトが切れています。プールから 接続を取得する前に、タイムアウト期間 が経過しました。プールされたすべての 接続が使用され、最大プール サイズに達したため、 が発生している可能性があります。

for (int i = 0; i < 1000; i++) 
    { 
     var address = new Address(); 
     address.City = "TEST"; 
     address.Save(); 
    } 

それが100に達するまでのコードは、その時点で(最大プールサイズを、おそらく偶然ではなく、)レコードを追加します:私は、コードの次のような単純なブロックで、この問題を再現するために管理している

上記の例外を除いて失敗します。その後、接続は5〜10分間保持され、その間にデータベースを使用しようとするすべての試みは上記の例外を与えます。

興味深いことに、これをローカルマシン上でVS(同じデータベースインスタンスと同じコードベース)で実行すると、1000個のレコードすべてを追加することができます。おそらくここと私のホストとの間の待ち時間は、データベースの呼び出しを十分に遅くするでしょうか?

これはローカルで動作すると考えられますが、これはサブソニックの問題ではないと思いますが、間違いがあります。また、コードや設定を変更して、多くのレコードを連続して追加しますか?

答えて

4

ARとSimpleRepoのperfテストを実行し、100,000レコードをループし、かなりハードな接続に問題を起こしました。perfチューニングの最初の停止です。

これは、読者が公開された状態でプレリリース版で問題が発生しているとのことです。私は数ヶ月前にそれを修正しました - あなたは最新のビットがあることを確認できますか?

また、レイテンシーが奇妙になる可能性があります。私は詳細を知らないが、それはそれのように見えます。

+0

おかげで、私は本当にそれがあなたのARの問題だった夢を見ませんでした。私は3.0.0.3を使用しています。 ホスティングプロバイダまたはASP.NETの設定が必要です。より奇妙なこと:100を追加すると、2つのブラウザウィンドウで同時にアドインを実行するページを読み込んでも、正常に繰り返し実行されます。 101を追加すると毎回失敗し、すべての接続が無期限にロックされます。 遅延をシミュレートして接続/切断の速度を低下させるたびに遅延が発生しても、それは役に立ちません。 .Add()コマンドの代わりに.Find()コマンドを実行するのと同じ効果があります。 –

+0

もう1つのデータポイントは、ARの外側でこれを行うことは、ホスト上で失敗しません:新しいsqlconnection、新しいsqlcommand、connを開く、テキストコマンドとして挿入cmdを実行する、cmdを終了する、connを閉じる)無限の数までおそらく、ARがホストの設定と競合する接続/コマンドをリリース/ディスポジションする方法に関するものでしょうか? –

1

私はMySQLを使用して同じ問題を抱えていました。新しいアクティブなレコードオブジェクトをインスタンス化してからsaveを呼び出すと、決して閉じられなかった接続が開かれました。

動作しているようだと思われる修正が見つかりました(kamsar http://github.com/subsonic/SubSonic-3.0/issues#issue/69に感謝します)明らかに問題はクローズド・リーダーによるものですか?

にSubSonicRepository.cs(3.0.0.3)にライン197を変更する "を使用して(DbDataReaderののRDRを= provider.ExecuteReader(クエリ))"(及び のような程度に適切な 範囲で使用ラッピング218)は が私のために解決したようです。

コードがこのようになり、接続リークが発生しなくなりました。

  //var rdr = provider.ExecuteReader(query); 
      using (System.Data.Common.DbDataReader rdr = provider.ExecuteReader(query)) 
      { 
       if (rdr.Read()) 
        result = rdr[0]; 
       // repopulate primary key column with newly generated ID 
       if (result != null && result != DBNull.Value) 
       { 

        try 
        { 
         var tbl = provider.FindOrCreateTable(typeof(T)); 
         var prop = item.GetType().GetProperty(tbl.PrimaryKey.Name); 
         var settable = result.ChangeTypeTo(prop.PropertyType); 
         prop.SetValue(item, settable, null); 

        } 
        catch (Exception x) 
        { 
         //swallow it - I don't like this per se but this is a convenience and we 
         //don't want to throw the whole thing just because we can't auto-set the value 
        } 
       } 
      } 
0

InnerSphereは正解です。私はRep Scoreを持っておらず、彼のポストに簡単に返信/コメントする方法を見つけられなかったので、投票できませんでした。

追加する唯一のことは、GitHubからコードを取得する場合です。この修正は既に含まれています。

トランクコードから作成したDLLをコンパイルして使用しても問題はありません。

0

私はすなわち、右の結果を得た後rdr.Close()を追加する必要がありました。:投稿用

if (rdr.Read()) 
    result = rdr[0]; 

rdr.Close(); 
関連する問題