近期,我發(fā)現(xiàn)測(cè)試環(huán)境的帳單數(shù)據(jù)有些異常,2月份之后的數(shù)據(jù)都沒(méi)有,在檢查演示環(huán)境后,發(fā)現(xiàn)演示環(huán)境正常。最后確定是測(cè)試環(huán)境在暴力測(cè)試或手動(dòng)改動(dòng)數(shù)據(jù)后,導(dǎo)致的問(wèn)題—數(shù)據(jù)庫(kù)沒(méi)有當(dāng)月平臺(tái)月帳單記錄,從而導(dǎo)致定時(shí)任務(wù)一直執(zhí)行不下去,月賬單記錄一直缺失。
優(yōu)化方案:
在每月1號(hào)凌晨2點(diǎn),因各種情況導(dǎo)致的平臺(tái)上月賬單記錄不存在的情況下,定時(shí)任務(wù)依舊能正常執(zhí)行,統(tǒng)計(jì)上個(gè)月的數(shù)據(jù),初始化當(dāng)月數(shù)據(jù)
(以后的版本sql中不會(huì)再有當(dāng)月月賬單記錄的插入)
優(yōu)化后的代碼:
改動(dòng)Java項(xiàng)目中StatisticsTaskServiceImpl類(lèi)下monthStatement()方法
/**
* 每月帳單定時(shí)任務(wù)
* 每月第一天2點(diǎn)執(zhí)行
* 獲取上個(gè)月所有的帳單記錄,然后通過(guò)累加獲取月帳單記錄
* 生成當(dāng)月帳單記錄,數(shù)值為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("每月帳單定時(shí)任務(wù),未查詢到上一個(gè)月的數(shù)據(jù),現(xiàn)在開(kāi)始初始化上個(gè)月數(shù)據(jù)");
// 初始化上一個(gè)月的數(shù)據(jù),值為0
platformMonthStatement = new PlatformMonthStatement();
platformMonthStatement.setDataDate(lastMonth);
// 初始化上一個(gè)月的商戶帳單數(shù)據(jù),值為0
merchantMonthStatementList = merchantMonthStatementService.findByMonth(lastMonth);
List<MerchantMonthStatement> tempMerchantMonthStatementList = CollUtil.newArrayList();
if (CollUtil.isNotEmpty(merchantMonthStatementList)) {
if (merIdList.size() != merchantMonthStatementList.size()) {
// 處理上個(gè)約沒(méi)有月賬單的商戶數(shù)據(jù)
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("每月帳單定時(shí)任務(wù),初始化上個(gè)月平臺(tái)月帳單失敗,觸發(fā)回滾");
e.setRollbackOnly();
return Boolean.FALSE;
}
save = merchantMonthStatementService.saveBatch(tempMerchantMonthStatementList, 100);
if (!save) {
LOGGER.error("每月帳單定時(shí)任務(wù),初始化上個(gè)月商戶月帳單失敗,觸發(fā)回滾");
e.setRollbackOnly();
return Boolean.FALSE;
}
return Boolean.TRUE;
});
if (!execute) {
LOGGER.error("每月帳單定時(shí)任務(wù),因沒(méi)有上個(gè)月數(shù)據(jù),初始化上個(gè)月數(shù)據(jù)時(shí)失敗");
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("每月帳單定時(shí)任務(wù),更新平臺(tái)月帳單失敗,觸發(fā)回滾");
e.setRollbackOnly();
return Boolean.FALSE;
}
save = merchantMonthStatementService.updateBatchById(finalMerchantMonthStatementList, 100);
if (!save) {
LOGGER.error("每月帳單定時(shí)任務(wù),更新商戶月帳單失敗,觸發(fā)回滾");
e.setRollbackOnly();
return Boolean.FALSE;
}
save = initMonthStatement(merIdList);
if (!save) {
LOGGER.error("每月帳單定時(shí)任務(wù),初始化平臺(tái)當(dāng)月帳單失敗,觸發(fā)回滾");
e.setRollbackOnly();
return Boolean.FALSE;
}
return Boolean.TRUE;
});
}
最后
在代碼改動(dòng)發(fā)布后,如果你跟我一樣,當(dāng)前2023-05月,在數(shù)據(jù)庫(kù)沒(méi)有的記錄的情況下,想看到統(tǒng)計(jì)的2023-04月的統(tǒng)計(jì)數(shù)據(jù)
在平臺(tái)端的管理后臺(tái),維護(hù) → 定時(shí)任務(wù)管理 → 定時(shí)任務(wù),找到每月帳單定時(shí)任務(wù),點(diǎn)擊觸發(fā)即可
就可以在eb_platform_month_statement和eb_merchant_month_statement表中看到對(duì)應(yīng)數(shù)據(jù)