需要为每个用户设置SqlDependency

时间:2013-08-08 05:28:10

标签: asp.net sql-server asp.net-mvc performance caching

系统范围

我有一个拥有大量用户的数据库(超过50,000)。任何时候都可能有100-200人登录并积极使用该系统。该系统是ASP.NET MVC 4,带有Sql Server 2008后端。对于数据访问,我们使用的是Dapper。

要求

我正在尝试构建一个具有以下属性的通知组件:

  1. 在[dbo.Assignment]表中创建新记录(使用OwnerId = [当前登录用户])时,我需要更新asp.net应用程序内的Cache。
  2. 我不希望收到任何非在线活动用户的通知,因为这会浪费大量资源)
  3. 具体问题:

    1. 我应该使用SqlDependency,SqlCacheDependency还是SqlNotification?

    2. 假设我们正在使用SqlDependency,当用户注销时如何删除Dependency.OnChange处理程序。

    3. 任何代码示例都会非常感激,因为这耗费了我一整天的时间来试图找出它。

    4. 以下是当前代码

       public IList<Notification> GetNotifications(string userName)
              {
                  Cache o = HttpContext.Current.Cache;
                  if (o["Notifications_" + userName] == null)
                  {
                      var notifications = new List<Notification>();
                      using (var cn = new SqlConnection(getSQLString()))
                      {
                          using (var cmd = cn.CreateCommand())
                          {
                              var parameter = new SqlParameter("Employee_Cd", SqlDbType.Char, 30) { Value = userName };
      
                              cmd.CommandType = CommandType.StoredProcedure;
                              cmd.CommandText = "Notifications.Assignments";
                              cmd.Parameters.Add(parameter);
                              cmd.Notification = null;
      
                              var dependency = new SqlCacheDependency(cmd);
      
                              cn.Open();
                              using (var dr = cmd.ExecuteReader())
                              {
                                  // this is where you build your cache
                                  while (dr.Read())
                                  {
                                      var obj = new Notification();
                                      obj.Name = dr["Name"].ToString();
                                      notifications.Add(obj);
                                  }
                                  dr.Close();
                              }
      
                              HttpContext.Current.Cache.Insert("Notifications_" + userName,
                                  notifications,
                                  dependency,
                                  DateTime.Now.AddDays(1D),
                                  Cache.NoSlidingExpiration);
                          }
                      }
                  }
                  return (List<Notification>) o["Notifications_" + userName];           
              }
      

      注意:我没有使用SqlDependencies的经验,因为直到今天我才真正需要使用它们。我很可能忽略了一些重要的事情。

1 个答案:

答案 0 :(得分:0)

我并没有真正使用这些技术中的任何一种技术,但是你可以自己创建一些替代方案来完成这项工作。

如果每次将新记录插入dbo.Assignment表时都需要更新缓存,为什么不在数据访问层中创建OnInserted事件来通知缓存对象刷新?

另一件事是在Assignemt表中创建INSERT触发器,另一个表看起来像这个dbo.Cache(LastUpdate datetime)。触发器将值插入到缓存表中,您的应用程序缓存可以像每隔X分钟或X秒一样ping此表,以查看是否需要缓存更新。 如果您需要在插入记录后立即刷新缓存,则触发器可能过度,因为您必须每秒ping一次缓存表,但如果您一次有200个在线用户可能不会产生太大影响数据库性能。

如果你想为很多表实现这些,有很多工作,但由于这只是一个表,这可能比实现内置缓存机制更快。