C# 如何安全有效地缓存ADO.NET命令?
我想使用这种模式:C# 如何安全有效地缓存ADO.NET命令?,c#,.net,asp.net,vb.net,ado.net,C#,.net,Asp.net,Vb.net,Ado.net,我想使用这种模式: SqlCommand com = new SqlCommand(sql, con); com.CommandType = CommandType.StoredProcedure;//um com.CommandTimeout = 120; //com.Connection = con; //EDIT: per suggestions below SqlParameter par; par = new SqlParameter("@id", SqlDbType.Int);
SqlCommand com = new SqlCommand(sql, con);
com.CommandType = CommandType.StoredProcedure;//um
com.CommandTimeout = 120;
//com.Connection = con; //EDIT: per suggestions below
SqlParameter par;
par = new SqlParameter("@id", SqlDbType.Int);
par.Direction = ParameterDirection.Input;
com.Parameters.Add(par);
HttpContext.Current.Cache["mycommand"] = com;
很明显,我不想遇到一些奇怪的问题,比如A个人从缓存中检索这个,更新param1,2个人从缓存中获取它,更新param2,以及每个运行命令的用户混合使用这两者
克隆从缓存中取出的命令可能比从头创建一个新命令更昂贵
ASP.NET缓存的线程安全性如何?我是否遗漏了其他潜在的陷阱?尽管存在线程问题,这种技术是否适用于无参数命令
克莱尔化:如果我想打自己的脚,我该如何瞄准?有没有一种方法可以锁定对缓存中对象的访问,以便对其进行序列化?缓存本身是线程安全的,但不会对放置在其中的对象赋予线程安全性。SqlCommand对象不是线程安全的,因此不是您希望缓存的类型 在这个场景中,最重要的事情是缓存为您处理的连接,您不应该试图自己处理这个问题 创建命令对象(即使是一个有许多参数的对象)与其执行相比仍然是微不足道的。除非你有相反的证据,否则不要试图缓存它们
项目面临的最大风险是过早优化。很简单:不要。如果您看不出这是错误的,您需要在ADO.NET上阅读更多内容。有很多文献解释了正确的方法:只需在需要时创建连接和命令,并确保正确处理它们。正如其他人所说,这是一个全面的坏主意。这是个坏主意的原因有很多 最重要的是,如果您处于高负载情况下,为每个用户存储命令将非常快地填满缓存,并且根据优先级等,将开始导致其他项从缓存中掉出,这应该仍然存在 使用ADO.NET,您确实应该在使用命令和连接时创建、使用并处理它们。就性能而言,我从来没有改变过这个系统……我也没有听说过很多其他人也这样做过
另外,正如其他人在代码示例中提到的,实际执行所需的连接无论如何都会丢失。为什么要缓存该命令?创建命令的开销很小,您只需新建几个对象并设置一些属性。我不认为这是个瓶颈
您希望缓存命令的结果,因为实际执行命令的成本(相对)较高。通常,您希望将共享缓存视为只读,这样就不必担心锁定和同步访问。缓存结果可以实现这一点。缓存结果,并且仅在resultcache为空时创建连接(和命令): 伪代码:
result = getResultFromCache(CacheKey)
if (result == null)
{
result = getResultFromDB();
InsertIntoCache(result,cacheKey);
}
return result;
我应该询问如何在ASP.NET缓存中锁定项目,而不是说我打算在缓存中放置什么
lock(Cache)
{
// do something with cache that otherwise wouldn't be threadsafe
}
参考资料:IMHO比链接文章中的更好的解决方案是在缓存中放置线程安全对象:这可以是非线程安全对象的线程安全包装。