есть проблема, создается такой BackgroundTask, запускается и периодически виснет в рандомном месте. сегодня из четырех запусков два раза зависал после строк
taskLog.debug("Снимаем признак со счетов ");
и
taskLog.debug("Создаем info " + processedCount + "+ для счетов, у которых info нет. Количество: " + billsWithoutInfo.size());
ошибок никаких не выдавал, с базой не работал, блокировок в базе не было. что может быть?
такая ситуация не первый раз, предыдущие два месяца тоже зависал в рандомном месте и приходилось перезапускать
new BackgroundTask<>(25L, TimeUnit.MINUTES, this) {
@Override
public Void run(TaskLifeCycle taskLifeCycle) throws Exception {
Logger taskLog = LoggerFactory.getLogger(this.getClass());
taskLog.debug(String.format("Начинаем закрытие периода. Счетов всего: %d", billsCount));
int processedCount = 0;
while (true) {
BigDecimal iterationCount = BigDecimal.ZERO.setScale(1, RoundingMode.UNNECESSARY);
taskLog.debug("Загружаем счета " + processedCount + "+");
List<Bill> bills = billService.getBillsForClosingPeriod(period, 100);
taskLog.debug("Счетов загружено " + bills.size());
if (bills.isEmpty()) {
taskLog.debug("Цикл окончен, выходим");
break;
}
taskLog.debug("Снимаем признак со счетов ");
for (Bill bill : bills) {
bill.setReadyToSendTo1c(true);
iterationCount = iterationCount.add(BigDecimal.valueOf(0.5));
if (iterationCount.remainder(BigDecimal.ONE).compareTo(new BigDecimal(0.5).setScale(1)) < 0)
taskLifeCycle.publish(processedCount + iterationCount.intValue());
}
taskLog.debug("Сохраняем счета " + processedCount + "+");
billService.saveBills(bills);
taskLog.debug("Счета " + processedCount + "+ сохранены");
iterationCount = new BigDecimal(bills.size() / 2).setScale(1, RoundingMode.UNNECESSARY);
if (iterationCount.remainder(BigDecimal.ONE).compareTo(new BigDecimal(0.5).setScale(1)) < 0)
taskLifeCycle.publish(processedCount + iterationCount.intValue());
List<String> numbers = bills.stream().map(Bill::getDocumentNumber).collect(Collectors.toList());
taskLog.debug("Загружаем info " + processedCount + "+");
List<BillInfo1C> infos = billService.get1CInfoByBillNumbers(numbers);
taskLog.debug("Info загружены " + infos.size() + ". Снимаем признак.");
for (BillInfo1C info : infos) {
info.setReadyToSendTo1c(true);
iterationCount = iterationCount.add(BigDecimal.valueOf(0.5));
if (iterationCount.remainder(BigDecimal.ONE).compareTo(new BigDecimal(0.5).setScale(1)) < 0)
taskLifeCycle.publish(processedCount + iterationCount.intValue());
}
Set<String> doneNumbers = infos.stream().map(BillInfo1C::getBillNumberLK).collect(Collectors.toSet());
List<Bill> billsWithoutInfo = bills.stream().filter(bill -> !doneNumbers.contains(bill.getDocumentNumber())).collect(Collectors.toList());
taskLog.debug("Создаем info " + processedCount + "+ для счетов, у которых info нет. Количество: " + billsWithoutInfo.size());
for (Bill bill : billsWithoutInfo) {
Map<String, Object> params = new HashMap<>();
params.put("billNumberLK", bill.getDocumentNumber());
params.put("period", bill.getPeriod());
params.put("inn", bill.getContragent().getInn());
params.put("contractNumber", bill.getContract().getMainContract() != null ?
bill.getContract().getMainContract().getNumber() :
bill.getContract().getNumber());
params.put("sum", bill.getSum());
params.put("readyToSendTo1c", true);
BillInfo1C info = billService.createInfoFrom1c(params,
false);
infos.add(info);
iterationCount = iterationCount.add(BigDecimal.valueOf(0.5));
if (iterationCount.remainder(BigDecimal.ONE).compareTo(new BigDecimal(0.5).setScale(1)) < 0)
taskLifeCycle.publish(processedCount + iterationCount.intValue());
}
taskLog.debug("Сохраняем info " + processedCount + "+. Количество: "+ infos.size());
billService.saveBillInfos(infos);
taskLog.debug("Info " + processedCount + "+ сохранены");
iterationCount = new BigDecimal(bills.size()).setScale(1, RoundingMode.UNNECESSARY);
taskLifeCycle.publish(processedCount + iterationCount.intValue());
processedCount += iterationCount.intValue();
}
//для верности, если были погрешности и processingCount < total
taskLifeCycle.publish(billsCount);
return null;
}
@Override
public void done(Void result) {
calculationConfig.setClosedPeriod(closingPeriod);
close(StandardOutcome.CLOSE);
}
@Override
public boolean handleException(Exception ex) {
Logger taskLog = LoggerFactory.getLogger(this.getClass());
taskLog.error("Ошибка при закрытии периода", ex);
ex.printStackTrace();
notifications.create(Notifications.NotificationType.ERROR)
.withCaption("При закрытии периода произошла ошибка")
.show();
return true;
}
}