最近修改的几个 bug,问题不大,查找起来却几番周折,汇总起来如下。
1.诡异电话号码
客服邮件反馈,很多用户服务热线变成了“0371-45875487”。看到这问题的第一反映是可能因为程序某个地方有人不小心写死了“0371-45875487”,因为服务热线对应数据库为一个字段ServiceTelephone,自然的把“0371-45875487”想象成了一个整体,在web解决方案中查找关键字“0371-45875487”,没有结果,数据库存储过程查找一遍,也没有结果,思路中断了,就先把数据处理了下,原因待查。
没几天,客服又反馈用户服务热线好多又变成了“0371-45875487”,再次超找问题,方式和上次一样,只是搜索关键词变成了“45875487”,没想到很顺利的定位到了问题。出现问题是在个人资料修改页,截取部分代码如下:
class="code_img_closed" src="/Upload/Images/2014052513/0015B68B3C38AA5B.gif" alt="" />logs_code_hide('3d778533-dc8a-4b88-8998-84eaa0017633',event)" src="/Upload/Images/2014052513/2B1B950FA3DF188F.gif" alt="" /><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,进而造成最终的计数有问题。
这问题告诉我们在重要操作上,一定要做好重复提交的判断。这问题发现的隐蔽性在于一个函数做了两件事,也和函数功能单一化原则相悖,合理的函数代码也有助于降低这种错误的概率。