最近修改的几个 bug,问题不大,查找起来却几番周折,汇总起来如下。

      1.诡异电话号码

      客服邮件反馈,很多用户服务热线变成了“0371-45875487”。看到这问题的第一反映是可能因为程序某个地方有人不小心写死了“0371-45875487”,因为服务热线对应数据库为一个字段ServiceTelephone,自然的把“0371-45875487”想象成了一个整体,在web解决方案中查找关键字“0371-45875487”,没有结果,数据库存储过程查找一遍,也没有结果,思路中断了,就先把数据处理了下,原因待查。

      没几天,客服又反馈用户服务热线好多又变成了“0371-45875487”,再次超找问题,方式和上次一样,只是搜索关键词变成了“45875487”,没想到很顺利的定位到了问题。出现问题是在个人资料修改页,截取部分代码如下:

                   <tr>
                        <td  align="right" valign="middle" bgcolor="#F9F9F9">
                            服务热线:</td>
                        <td align="left" valign="middle">
                            <input name="mendiantelephone1" type="text" id="mendiantelephone1" style="width: 30px;"
                                value="0371" size="4" maxlength="5" runat="server" />
                            -
                            <input name="mendiantelephone2" type="text" id="mendiantelephone2" style="width: 50px;"
                                value="45875487" maxlength="8" runat="server" /></td>
                    </tr>
资料修改aspx代码
                if (!string.IsNullOrEmpty(AgentInfo.MendianTelephone))
                {
                    mendiantelephone1.Value = AgentInfo.MendianTelephone.IndexOf("-") < 0 ? "" : AgentInfo.MendianTelephone.Substring(0, AgentInfo.MendianTelephone.IndexOf("-"));
                    mendiantelephone2.Value = AgentInfo.MendianTelephone.IndexOf("-") < 0 ? AgentInfo.MendianTelephone : AgentInfo.MendianTelephone.Substring(AgentInfo.MendianTelephone.IndexOf("-") + 1);
                }
资料修改aspx.cs代码

      如果用户原来没有填写服务热线,在修改页这两个控件的值默认成了“0371”和“45875487”,用户好不知情的情况下把自己的服务热线修改错了。问题修改也很容易,直接把默认值去掉即可。

      这问题告诉我们看似诡异的问题肯定也有其原因的,查找问题时可以缩小搜索关键词。

      2.同名缓存带来的问题

      问题描述:惠州房源信息,同一楼盘对应的区县、商圈竟然出现了不同值,如小区三千俊林对应的区县商圈出现了两组“惠州 惠阳区”和“惠阳 淡水"。查找原因原来是用到了同名缓存造成的,代码如下:

        /// <summary>
        /// 根据newcode 获取楼盘字典信息
        /// </summary>
        public DataTable GetBuildingDicByNewcode(CityBase citySite, long newcode, string projtype)
        {
            DataTable dt = new DataTable();
            string oewname = "districtinfo_bus_around" + newcode.ToString() + "_" + projtype + "new";
            string cachename = CacheType.housedic + "_" + oewname;

            //先取数据缓存
            if (this.MemCache.KeyExists(cachename))
            {
                dt = this.MemCache.Get<DataTable>(cachename);
            }
            else
            {
                dt = buildingErrorData.GetBuildingDicByNewcode(citySite, newcode, projtype);
                this.MemCache.Set(cachename, dt, DateTime.Now.AddDays(1));
            }
            return dt;
        }

      区县商圈都是根据楼盘编号获取的,而楼盘编号在全国都是唯一的,不会重复,这段代码看似没什么问题,那问题在哪呢?原来还有一个异地楼盘业务,就是深圳可以调用惠州的楼盘,调用的时候惠州就成了深圳的区县了,相当于深圳和惠州同一楼盘的区县商圈属性不同。

      这问题出现是因为新业务的出现造成了老代码出现问题,新做业务时方方面面得考虑周全才行。

      3.重复提交问题

      问题描述:在用户进行放心房操作时,有个计数的字段,每设置一条计数字段+1,每取消一次计算字段-1,但这计数字段却出现了负数的情况。查找问题,最终出现在了用户重复提交上,而且从数据上看是有用户发现了这一漏洞,恶意提交了数据。

        public bool CancelRealHouse(CityBase citySite, HouseOptEntity optEntity, HouseType htype = HouseType.Sale)
        {
            //刷新房源并设置标签
            rowCount = houseDAO.UpdateRealHouseStatus(citySite, htype, optEntity.AgentId, optEntity.HouseIds, string.Empty, false);

            //调整操作数,只有设置上了放心房标签才会去调整
            if (rowCount > 0)
            {
                this.houseBizMember.AgentPowerUsingBiz.HouseAction(citySite, htype, HouseAction.UnRealHouse, optEntity.AgentId, rowCount, rowCount, 0);
            }
        }

        public int UpdateRealHouseStatus(CityBase citySite, HouseType houseType, int agentId, List<int> houseIds, string infoCode, bool isSet)
        {
            int retVal = 0;
            int isRealHouse = isSet ? 1 : 0;
            DBHelper db = DBHelper.GetDBHelper(BusinessType.AgentHouseWrite, citySite, agentId);
            string tableName = GetTableName(citySite, houseType, true);
            string refTableName = GetRefreshTableName(citySite, houseType);
            string houseIdsStr = string.Join<int>(",", houseIds);
            string sql = sql = string.Format("update {0} set isRealHouse = {1} where agentid={2} and status = 1 and isRealHouse != {1} and houseid in ({3});", tableName, isRealHouse, agentId, houseIdsStr);
            retVal = db.ExecuteNonQuery(CommandType.Text, sql);
            sql = string.Format("update s set s.registdate = getdate(),s.dtimestamp=getdate() from {0} s inner join {1} h with(nolock) on s.houseid = h.houseid where h.agentid={2} and h.[status]=1 and h.houseid in ({3})", refTableName, tableName, agentId, houseIdsStr);
            retVal = db.ExecuteNonQuery(CommandType.Text, sql);

            return retVal;
        }

       问题出现在函数UpdateRealHouseStatus()上,这个函数执行了两个操作,一个是更新是否放心房,其实这步骤是没问题的,取消状态时,如果原本就是取消状态,这个返回的就是0,但问题出现在第二个操作上,重新给返回值赋值了,致使重复提交了返回值仍然为1,进而造成最终的计数有问题。

       这问题告诉我们在重要操作上,一定要做好重复提交的判断。这问题发现的隐蔽性在于一个函数做了两件事,也和函数功能单一化原则相悖,合理的函数代码也有助于降低这种错误的概率。

posted on 2014-05-25 11:50  陈晨  阅读(1615)  评论(1编辑  收藏  举报