近期,我发现测试环境的帐单数据有些异常,2月份之后的数据都没有,在检查演示环境后,发现演示环境正常。最后确定是测试环境在暴力测试或手动改动数据后,导致的问题—数据库没有当月平台月帐单记录,从而导致定时任务一直执行不下去,月账单记录一直缺失。
优化方案:
在每月1号凌晨2点,因各种情况导致的平台上月账单记录不存在的情况下,定时任务依旧能正常执行,统计上个月的数据,初始化当月数据
(以后的版本sql中不会再有当月月账单记录的插入)
优化后的代码:
改动Java项目中StatisticsTaskServiceImpl类下monthStatement()方法
/**
* 每月帐单定时任务
* 每月第一天2点执行
* 获取上个月所有的帐单记录,然后通过累加获取月帐单记录
* 生成当月帐单记录,数值为0
*/
@Override
public void monthStatement() {
String lastMonth = DateUtil.lastMonth().toString(DateConstants.DATE_FORMAT_MONTH);
PlatformMonthStatement platformMonthStatement = platformMonthStatementService.getByMonth(lastMonth);
List<MerchantMonthStatement> merchantMonthStatementList = CollUtil.newArrayList();
List<Integer> merIdList = merchantService.getAllId();
if (ObjectUtil.isNull(platformMonthStatement)) {
LOGGER.error("每月帐单定时任务,未查询到上一个月的数据,现在开始初始化上个月数据");
// 初始化上一个月的数据,值为0
platformMonthStatement = new PlatformMonthStatement();
platformMonthStatement.setDataDate(lastMonth);
// 初始化上一个月的商户帐单数据,值为0
merchantMonthStatementList = merchantMonthStatementService.findByMonth(lastMonth);
List<MerchantMonthStatement> tempMerchantMonthStatementList = CollUtil.newArrayList();
if (CollUtil.isNotEmpty(merchantMonthStatementList)) {
if (merIdList.size() != merchantMonthStatementList.size()) {
// 处理上个约没有月账单的商户数据
List<Integer> staMerIdList = merchantMonthStatementList.stream().map(MerchantMonthStatement::getMerId).collect(Collectors.toList());
for (Integer merId : merIdList) {
if (!staMerIdList.contains(merId)) {
MerchantMonthStatement merchantMonthStatement = new MerchantMonthStatement();
merchantMonthStatement.setMerId(merId);
merchantMonthStatement.setDataDate(lastMonth);
tempMerchantMonthStatementList.add(merchantMonthStatement);
}
}
}
} else {
merIdList.forEach(merId -> {
MerchantMonthStatement merchantMonthStatement = new MerchantMonthStatement();
merchantMonthStatement.setMerId(merId);
merchantMonthStatement.setDataDate(lastMonth);
tempMerchantMonthStatementList.add(merchantMonthStatement);
});
}
PlatformMonthStatement finalPlatformMonthStatement = platformMonthStatement;
Boolean execute = transactionTemplate.execute(e -> {
boolean save = platformMonthStatementService.save(finalPlatformMonthStatement);
if (!save) {
LOGGER.error("每月帐单定时任务,初始化上个月平台月帐单失败,触发回滚");
e.setRollbackOnly();
return Boolean.FALSE;
}
save = merchantMonthStatementService.saveBatch(tempMerchantMonthStatementList, 100);
if (!save) {
LOGGER.error("每月帐单定时任务,初始化上个月商户月帐单失败,触发回滚");
e.setRollbackOnly();
return Boolean.FALSE;
}
return Boolean.TRUE;
});
if (!execute) {
LOGGER.error("每月帐单定时任务,因没有上个月数据,初始化上个月数据时失败");
return;
}
platformMonthStatement.setId(finalPlatformMonthStatement.getId());
if (CollUtil.isNotEmpty(tempMerchantMonthStatementList)) {
merchantMonthStatementList.addAll(tempMerchantMonthStatementList);
}
}
writePlatformMonthStatement(platformMonthStatement);
writeMerchantMonthStatement(merchantMonthStatementList, lastMonth);
PlatformMonthStatement finalTempPlatformMonthStatement = platformMonthStatement;
List<MerchantMonthStatement> finalMerchantMonthStatementList = merchantMonthStatementList;
transactionTemplate.execute(e -> {
boolean save = platformMonthStatementService.updateById(finalTempPlatformMonthStatement);
if (!save) {
LOGGER.error("每月帐单定时任务,更新平台月帐单失败,触发回滚");
e.setRollbackOnly();
return Boolean.FALSE;
}
save = merchantMonthStatementService.updateBatchById(finalMerchantMonthStatementList, 100);
if (!save) {
LOGGER.error("每月帐单定时任务,更新商户月帐单失败,触发回滚");
e.setRollbackOnly();
return Boolean.FALSE;
}
save = initMonthStatement(merIdList);
if (!save) {
LOGGER.error("每月帐单定时任务,初始化平台当月帐单失败,触发回滚");
e.setRollbackOnly();
return Boolean.FALSE;
}
return Boolean.TRUE;
});
}
最后
在代码改动发布后,如果你跟我一样,当前2023-05月,在数据库没有的记录的情况下,想看到统计的2023-04月的统计数据
在平台端的管理后台,维护 → 定时任务管理 → 定时任务,找到每月帐单定时任务,点击触发即可
就可以在eb_platform_month_statement和eb_merchant_month_statement表中看到对应数据
{{item.user_info.nickname ? item.user_info.nickname : item.user_name}}
作者 管理员 企业
{{itemf.name}}
{{itemc.user_info.nickname}}
{{itemc.user_name}}
回复 {{itemc.comment_user_info.nickname}}
{{itemf.name}}