我现在页面上有一个[回访列表],只要是登录的人都能看到这个[回访列表],然后点击[回访]连接进入[回访详细页面]进行回访。现在是我如何能够避免一个人在点击[回访]后进入[回访详细页面]。另一个人在点击[回访]的时候就提示它当前信息已经有人在回访呢?我本来想的是一个人在点击[回访]后进入回访详细页面,马上就把这个回访的[状态]改为[正在回访],当另一个人再点击[回访]进入[回访详细页面]时就提示它,当前回访已经有人在回访了。但是后来一想,如果回访的这个人突然死机或是关掉IE了,那么状态不就改不回来了么?这种任务任何人都能执行,并且还要防止两人共同执行同一个任务的情况要怎么设计系统来解决啊?我看数据库中有什么锁之类的,但是它只能防止一个我在更新数据的时候其它人不能读取。有没有办法让我在读取查看这条数据的时候其它人就不能查看呀?各位高手老大们应该也碰见过这样的问题吧,有没有什么好的解决思路啊?希望各位高手老大不吝赐教!

解决方案 »

  1.   

    用Cache来保存锁定情况
        #region 锁定栏目    public bool CheckLocked()
        {
            bool bl = false;
            if (Cache["LockedPageList"] != null)
            {
                Hashtable ht = (Hashtable)Cache["LockedPageList"];
                
                if (ht != null)
                {
                    int colId = GetQueryId("id");
                    //检查用户自己是否已经在编辑其他栏目
                    foreach (DictionaryEntry de in ht)
                    {
                        if (de.Value.ToString() == HttpContext.Current.User.Identity.Name)
                        {
                            if (de.Key.ToString() != colId.ToString())
                            {
                                string url = Request.Url.ToString().ToLower();
                                url = url.Replace("id=" + colId, "id=" + de.Key);
                                return true;
                            }
                        }
                    }                //检查是否已经有其他用户在编辑此栏目
                    if (ht.ContainsKey(colId))
                    {
                        if (ht[colId].ToString() != HttpContext.Current.User.Identity.Name)
                        {
                            return true;
                        }
                    }
                }
            }
            return bl;
        }    protected int GetQueryId(string key)
        {
            object o = Request.QueryString[key];        if (null == o)
            {
                return -1;
            }        try
            {
                return Int32.Parse(o.ToString());
            }
            catch (Exception)
            {        }
            return -1;
        }    #endregion 锁定栏目
      

  2.   

    锁不行,可以用select * from tb with (rowlock)锁行,但也只限于更新
    估计要做到及时的状态很难,毕竟是bs,用户什么时候离开或关闭页面不容易得到
      

  3.   


       #region 加锁栏目    /// <summary>
        /// 加锁到某个栏目的页面
        /// </summary>
        /// <param name="pageID">栏目ID</param>
        public static void LockedColumn(int columnID)
        {
            Hashtable htLock = null;
            if (HttpContext.Current.Cache["LockedPageList"] != null)
            {
                htLock = (Hashtable)HttpContext.Current.Cache["LockedPageList"];            if (!htLock.ContainsKey(columnID))
                    htLock.Add(columnID, HttpContext.Current.User.Identity.Name);
            }
            else
            {
                htLock = new Hashtable();
                htLock.Add(columnID, HttpContext.Current.User.Identity.Name);
            }
            HttpContext.Current.Cache.Insert("LockedPageList", htLock, null,
                    System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromHours(2));
        }    /// <summary>
        /// 说明:清空某个用户的栏目锁
        /// 创建人:DC
        /// 创建时间:20071112
        /// 修改人:
        /// 修改时间:
        /// </summary>
        public static void RefreshCache()
        {
            if (HttpContext.Current.Cache["LockedPageList"] != null)
            {
                Hashtable ht = (Hashtable)HttpContext.Current.Cache["LockedPageList"];
                Hashtable htNew = new Hashtable();
                if (ht != null)
                {
                    htNew = (Hashtable)ht.Clone();
                    foreach (DictionaryEntry de in ht)
                    {
                        if (de.Value.ToString() == HttpContext.Current.User.Identity.Name)
                        {
                            htNew.Remove(de.Key);
                        }
                    }
                }
                HttpContext.Current.Cache["LockedPageList"] = htNew;
            }
        }
        #endregion
    用Cache的话,关键是要设置个失效时间,并且在用户退出系统时要清除锁
      

  4.   

    看到了,谢谢大家。fellowcheng 老大方案很棒!我想问问有没有更完美的能够及时获取的解决方案啊,而不是通过缓存等方式,这种时间都很不准确。难道数据库除了更新外,读取的时候没有这种锁么,只能够一个人读?