背景
店铺功能已经开发完成,新开发了店铺装修功能,需要将之前开通了店铺的,在新的表里面刷其店铺装修初始数据。涉及到两张表如下:
店铺表:
@Data
@EqualsAndHashCode(callSuper = false)
@Document(collection = "shop")
@CompoundIndexes({
@CompoundIndex(name = "shopNo", def = "{'shopNo': 1}", unique = true),
@CompoundIndex(name = "name", def = "{'name': 1}"),
@CompoundIndex(name = "userId", def = "{'userId': 1}"),
@CompoundIndex(name = "domain", def = "{'domain': 1}", unique = true)
})
public class ShopDoc extends BaseDoc {
@Id
ObjectId id;
Long createTime = System.currentTimeMillis();
Long updateTime = System.currentTimeMillis();
/**
* 店铺名称
*/
String name;
/**
* 店铺编号
*/
String shopNo;
/**
* logo
*/
String logo;
/**
* 公告
*/
String shopNotice;
/**
* 店铺描述
*/
String intro;
...
店铺装修表:
@Data
@EqualsAndHashCode(callSuper = false)
@Document(collection = "shop_decorate")
@CompoundIndexes({
@CompoundIndex(name = "shopId", def = "{'shopId': 1}")
})
public class ShopDecorateDoc extends BaseDoc{
@Id
ObjectId id;
Long createTime = System.currentTimeMillis();
Long updateTime = System.currentTimeMillis();
/**
* 店铺id
*/
ObjectId shopId;
/**
* 顶部轮播图
*/
Boolean topBannerSwitch;
/**
* 轮播图
*/
List<BannerSetting> bannerSettings;
/**
* 封面设置
*/
CoverSetting coverSetting;
/**
* 快捷入口
*/
Boolean shortCutSwitch;
...
错误产生代码
用的是mongodb数据库,现在因为店铺装修线上已经有部分人在使用,所以需要将没有设置过店铺装修的店铺一律加上初始化的数据,原本是一个很简单的功能,但是由于代码的不严谨,导致了将设置过店铺装修的店铺信息也被初始化了。现在看看原因产生的代码:
@Override
public List<String> getAllShopIdsExcludeDecorate() {
// 所有店铺表信息
List<ShopDoc> shopDocs = mongoTemplate.findAll(ShopDoc.class);
List<String> shopIds = new ArrayList<>();
for (ShopDoc shopDoc:shopDocs){
shopIds.add(shopDoc.getId().toString());
}
// 所有店铺装修表信息
List<ShopDecorateDoc> shopDecorateDocs = mongoTemplate.findAll(ShopDecorateDoc.class);
List<String> shopDecorateIds = new ArrayList<>();
for (ShopDecorateDoc shopDecorateDoc:shopDecorateDocs){
shopDecorateIds.add(shopDecorateDoc.getId().toString());
}
// 排除店铺装修表的所有id,得到该刷数据的店铺id
for (String str:shopIds){
if (shopDecorateIds.contains(str)){
shopIds.remove(str);
}
}
return shopIds;
}
其实是很简单的代码,检验代码如下
@ApiOperation(value = "统一初始化店铺装修信息", httpMethod = "Get")
@GetMapping(value = "/shops/shopDecorateConfig")
public JsonResponse getShopDecorateInit() {
List<String> ids = shopService.getAllShopIdsExcludeDecorate();
// 进行验证了店铺装修其中一个店铺是否存在,debug显示false
boolean yes = ids.contains("5e7c61d494df720006116eab");
ShopDecorateParam shopDecorateParam = shopDecorateConfig.getShopSettings();
for (String str:ids){
shopService.upsertShopDecorate(new ObjectId(str), shopDecorateParam);
}
return new JsonResponse(shopService.getAllShopIdsExcludeDecorate());
}
这里通过了我的boolean值检验,又因为数据量少,然后我就愉快大胆的刷库了
错误原因
店铺装修这张表是有两个id的,我拿到了数据表的id,却不是店铺id。
很显然是因为代码不严谨导致了这个错误,因为刷库的时候,测试环境出了点问题,开发这个功能的时候一直用的线上库,再加上使用这个功能的客户很少,因为还没有推广,所以我就大意了。
错误原因总结
大致有以下几点:
- 周一上午,隔了两天继续做这个功能收尾工作,很困又饿,程序员注意力不集中,大意了
- 程序员代码命名除了问题
《阿里巴巴Java开发》手册里面要求命名要词答意,我这个地方如果命名是店铺装修表shopIds,那么写代码是不会出现这种情况的,以后命名一定要望文知义。
- 验证处的代码逻辑不够严谨
通过了代码检验,检验方法出现了问题,需要加上在数据库里面分别count两张表的数据条数,将其相减之后比较list的size是否与得到的条数一致。
解决办法
解决方式是数据库回滚,回滚到一个小时之前。倒是没有造成多大经济损失,但是我自己非常的难过,由于是实习生公司文化也很好,领导们没有责怪,我选择了给大家买一箱安慕希作为赔罪,特意记下来此次bug鞭策自己。
总结
- 平时编码就要养成良好的习惯,代码注释和代码命名规范要严格遵守,很多时候不是写给别人看而是写给自己看。
- 平时学习过程中注重分享,有分享才能有进步。