以下是代码段:
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
?
这可能是真的吗?还有什么其他解释?
编辑:我在[{1}} OnCreated
方法中添加了一个记录器,并为数据上下文及其{{1}记录了MyDataContext
的值属性。那里没有重复,所以我猜他们没有共享同一个对象 - 至少,不是正常使用。自安装日志记录以来,没有看到“open datareader”错误。但即使他们没有使用相同的连接对象,也许它们仍然与DB共享相同的连接?