背景
由于數(shù)據(jù)同步鏈路太長,偶爾出現(xiàn)數(shù)據(jù)不一致的bad case,為了解決該問題,添加了全量數(shù)據(jù)的補償任務(wù),即分批次掃描全表數(shù)據(jù),然后串行同步
現(xiàn)象
上游同學(xué)凌晨2點群里同步,某批id一天更新次數(shù)高達25w次,影響到了上游數(shù)據(jù)表性能
異常編碼
import java.util.ArrayList;
import java.util.List;
public class Task {
void sync() {
while (true) {
Long offset = 0L;
try {
List<Shop> res = ShopDao.get(offset, 20L);/*每次查20條*/
for (Shop shop : res) {
try {
del(shop);
} catch (ServiceException e) {
/*打印日志*/
}
}
offset = res.get(res.size()-1).id; /*id為數(shù)據(jù)表主鍵id*/
}catch (Exception e){
/* 打印日志*/
}
}
}
void del(Shop shop) throws ServiceException {
throw new ServiceException();
}
}
class ShopDao {
static List<Shop> get(Long offset, Long limit) {
/* "select * from shopTable where id>#{offset} limit #{limit} order by id";*/
return new ArrayList<>();
}
}
class Shop {
Long id;
}
class ServiceException extends Exception {
}
異常原因
串行執(zhí)行批量任務(wù)時,執(zhí)行任務(wù)組只catch了ServiceException,但是在這個批次中,有一個店鋪拋出的異常并不是ServiceException,導(dǎo)致了查詢數(shù)據(jù)表的fromId每次都得不到更新,即進入死循環(huán)
解決
將每組任務(wù)的catch異常改為Exception
反思
- 編寫代碼時注意細節(jié)
- 使用while(count<n)替代while(true),n為大于任務(wù)數(shù)量的異常定值,在執(zhí)行完任務(wù)時,記錄n,如果n>數(shù)據(jù)表的數(shù)量,則說明代碼存在異常