我想使用这种模式:
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和运行命令的每个用户混合使用两者。 / p>
克隆从缓存中取出的命令可能比从头开始创建一个新命令更加昂贵。
ASP.NET缓存的线程安全性如何?我错过了任何其他潜在的陷阱吗?尽管存在线程问题,这种技术是否适用于无参数命令?
Clarefication:如果我想用脚比喻自己,我该如何瞄准?有没有办法锁定对缓存中对象的访问权限,以便序列化访问?
答案 0 :(得分:7)
很简单:不要。如果你看不出这是错的,你需要阅读更多关于ADO.NET的内容。有很多文献解释了正确的方法:只需在需要时创建连接和命令,并确保妥善处理它们。
答案 1 :(得分:5)
缓存本身是线程安全的,但不会对放在其中的对象赋予线程安全性。 SqlCommand对象不是线程安全的,因此不是你想要缓存的那种东西。
在这种情况下,最重要的是缓存为您处理的连接,您不应该自己尝试照顾它。
与其执行相比,命令对象(即使是具有许多参数的对象)的创建仍将是花生。除非您有证据,否则不要尝试缓存它们。
您项目面临的最大风险是过早优化。
答案 2 :(得分:1)
正如其他人所说,这只是一个坏主意。有很多理由说明这是一个坏主意。
最重要的是,如果您处于高负载状态,为每个用户存储命令将真正快速填满缓存,并根据优先级等,将开始导致其他项目失效缓存,真的应该还在那里。
使用ADO.NET,你真的应该在使用它们时创建,使用,然后处理你的命令和连接。表现明智,我从来没有必要改变这个系统.....我也没有真正听过很多其他的系统。
此外,正如其他人提到的代码示例一样,实际执行所需的连接无论如何都会丢失。
答案 3 :(得分:1)
为什么要缓存命令?创建命令的开销很小 - 你只需要新建几个对象并设置一些属性。我永远不会认为这是一个瓶颈......
您希望缓存命令的结果,因为实际正在执行命令(相对)昂贵。而且,通常,您希望将共享缓存视为只读,这样您就不必担心锁定和同步访问。缓存结果可实现这一目标。
答案 4 :(得分:1)
我应该问过如何在ASP.NET缓存中锁定一个项目,而不是说我打算放入缓存中。
lock(Cache)
{
// do something with cache that otherwise wouldn't be threadsafe
}
参考:http://www.codeguru.com/csharp/.net/net_asp/article.php/c5363
答案 5 :(得分:0)
缓存结果,只有在resultcache为null时才创建连接(和命令):
伪码:
result = getResultFromCache(CacheKey)
if (result == null)
{
result = getResultFromDB();
InsertIntoCache(result,cacheKey);
}
return result;