背景
店鋪功能已經開發完成,新開發了店鋪裝修功能,需要將之前開通了店鋪的,在新的表裏面刷其店鋪裝修初始數據。涉及到兩張表如下:
店鋪表:
@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鞭策自己。
總結
- 平時編碼就要養成良好的習慣,代碼註釋和代碼命名規範要嚴格遵守,很多時候不是寫給別人看而是寫給自己看。
- 平時學習過程中注重分享,有分享纔能有進步。