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];
}    

这段代码大部分时间都可以正常工作。然而,在负载测试中,我们有时会在TryGet()方法中遇到臭名昭著的“Open DataReader”错误,调用堆栈显示它通过了GetValue()

对于我的一生,我看不出这是怎么可能的。我显然using在调用周围使用了一个块TryGet,带有一个新实例MyDataContext,并且只有一个查询。那么那里怎么可能DataReader已经有一个开放空间呢?

MyDataContext除非...... (显然继承自)的所有实例之间存在一些共享连接DataContext,并且当两个线程同时尝试使用该Connection属性时,即使是两个不同的数据上下文,不知何故它们都在访问相同的DataReader

这可能是真的吗?还能有什么其他解释?

编辑:我在OnCreated方法中放置了一个记录器,MyDataContext并记录了GetHashCode数据上下文及其Connection属性的值。那里没有重复,所以我猜他们没有共享同一个对象 - 至少,不是在正常使用中。自安装日志以来,没有看到“打开数据读取器”错误。但即使他们没有使用相同的连接对象,也许他们仍然以某种方式共享与数据库的相同连接?

4

0 回答 0