如何安全有效地缓存ADO.NET命令?

时间:2008-12-21 15:52:07

标签: 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);
par.Direction = ParameterDirection.Input;

com.Parameters.Add(par);

HttpContext.Current.Cache["mycommand"] = com;

显然,我不想遇到奇怪的问题,比如人A从缓存中检索这个问题,更新param1,人2从缓存中获取它,并更新param2和运行命令的每个用户混合使用两者。 / p>

克隆从缓存中取出的命令可能比从头开始创建一个新命令更加昂贵。

ASP.NET缓存的线程安全性如何?我错过了任何其他潜在的陷阱吗?尽管存在线程问题,这种技术是否适用于无参数命令?

Clarefication:如果我想用脚比喻自己,我该如何瞄准?有没有办法锁定对缓存中对象的访问权限,以便序列化访问?

6 个答案:

答案 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;