package jnpf.dmsService;
|
|
import jnpf.audit.sdk.annotation.AuditLog;
|
import jnpf.dmsEntity.fenfa.DmsBupinghengRetry;
|
import jnpf.dmsMapper.DmsBupinghengRetryMapper;
|
import jnpf.exception.DataException;
|
import lombok.RequiredArgsConstructor;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.stereotype.Service;
|
import java.util.UUID;
|
|
@Slf4j
|
@Service
|
@EnableScheduling
|
@RequiredArgsConstructor
|
@ConditionalOnProperty(name = "dms.imbalance.retry.enabled", havingValue = "true")
|
public class DmsBupinghengRetryJob {
|
private final DmsBupinghengRetryMapper mapper;
|
private final DmsWenjianBupinghengService service;
|
@Value("${dms.imbalance.retry.batch-size:100}")
|
private int batchSize = 100;
|
@Value("${dms.imbalance.retry.max-attempts:5}")
|
private int maxAttempts = 5;
|
|
@Scheduled(cron = "${dms.imbalance.retry.cron:0 */5 * * * ?}")
|
@AuditLog(action = "FILE_DISTRIBUTION_IMBALANCE_SCAN", bizCodeExpr = "''", recordSuccess = false)
|
public void retryPending() {
|
// 每次 executeScheduled 经过独立代理事务;领取和失败回执不会随业务回滚丢失。
|
for (DmsBupinghengRetry candidate : mapper.selectPending(Math.max(1, Math.min(batchSize, 1000)), Math.max(1, maxAttempts))) {
|
String token = UUID.randomUUID().toString();
|
try {
|
if (mapper.claim(candidate, token, Math.max(1, maxAttempts)) != 1) continue;
|
DmsBupinghengRetry task = mapper.selectClaim(candidate, token);
|
if (task == null) continue;
|
try {
|
service.executeScheduled(task.getTenantId(), task.getDocumentId(), task.getVersion());
|
mapper.finish(task, token, true, null, 0);
|
} catch (Exception error) {
|
boolean stop = error instanceof DataException || task.getAttempts() >= Math.max(1, maxAttempts);
|
int delay = Math.min(3600, 300 * (1 << Math.min(task.getAttempts() - 1, 4)));
|
String message = error.getMessage() == null ? error.getClass().getSimpleName() : error.getMessage();
|
mapper.finish(task, token, stop, message.substring(0, Math.min(message.length(), 1000)), delay);
|
log.warn("不平衡补偿失败 tenant={} document={} attempts={} stopped={}",
|
task.getTenantId(), task.getDocumentId(), task.getAttempts(), stop);
|
}
|
} catch (Exception error) {
|
// 回执写入失败由持久租约到期恢复;不能终止本批其余登记单。
|
log.error("不平衡补偿调度异常 tenant={} document={}", candidate.getTenantId(), candidate.getDocumentId(), error);
|
}
|
}
|
}
|
}
|