1

コード スニペットを次に示します。

private static ApplicationParameter TryGet(MyDataContext ctxt, string parameterName) {
  return ctxt.GetTable<ApplicationParameter>().Where(p => p.Name.ToLower() == parameterName.ToLower()).SingleOrDefault();
}

private static Dictionary<string, string> _cache = new Dictionary<string, string>();

public static string GetValue(string parameterName) {
  if (!_cache.ContainsKey(parameterName))
    using (var ctxt = new MyDataContext()) {
      var ap = TryGet(ctxt, parameterName);
      if (ap != null)
        _cache[parameterName] = ap.Value;
      else
        _cache[parameterName] = null;
    }
    return _cache[parameterName];
}    

ほとんどの場合、このコードは問題なく動作します。ただし、負荷テストでは、悪名高い「Open DataReader」エラーがTryGet()メソッドで発生することがあり、コール スタックはそれが通過したことを示していますGetValue()

私の人生では、これがどのように可能かわかりません。usingの呼び出しの周りにブロックを使用していることは明らかTryGetで、 の新しいインスタンスがありMyDataContext、クエリは 1 つしかありません。DataReaderでは、どうしてすでにそこにオープンがある可能性があるのでしょうか?

MyDataContext(明らかに から継承する)のすべてのインスタンス間に何らかの共有接続がDataContextあり、2 つのスレッドが同時にConnectionプロパティを使用しようとすると、2 つの異なるデータ コンテキストであっても、どういうわけか両方とも同じにアクセスしているDataReader場合を除きます。

これは本当でしょうか?他にどんな説明があるでしょうか?

編集:OnCreatedのメソッドにロガーを配置し、データ コンテキストとそのプロパティの両方MyDataContextの値をログに記録しました。そこには重複がないので、同じオブジェクトを共有していないと思います-少なくとも、通常の使用法では. ロギングをインストールして以来、「open datareader」エラーは発生していません。しかし、同じ接続オブジェクトを使用していなくても、何らかの理由で DB への同じ接続を共有しているのではないでしょうか?GetHashCodeConnection

4

0 に答える 0