背景
由于数据同步链路太长,偶尔出现数据不一致的bad case,为了解决该问题,添加了全量数据的补偿任务,即分批次扫描全表数据,然后串行同步
现象
上游同学凌晨2点群里同步,某批id一天更新次数高达25w次,影响到了上游数据表性能
异常编码
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为数据表主键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 {
}
异常原因
串行执行批量任务时,执行任务组只catch了ServiceException,但是在这个批次中,有一个店铺抛出的异常并不是ServiceException,导致了查询数据表的fromId每次都得不到更新,即进入死循环
解决
将每组任务的catch异常改为Exception
反思
- 编写代码时注意细节
- 使用while(count<n)替代while(true),n为大于任务数量的异常定值,在执行完任务时,记录n,如果n>数据表的数量,则说明代码存在异常
网友评论