У нас настроена задача "Закрытие статуса NPay договоров по балансу" на запуск в 01:10 каждый день. Время выполнения задачи от одной минуты (не первого числа, когда закрываются единицы) до десяти минут (первого числа, когда закрываются сразу очень много договоров). Задача "Calculator", которая подсчитывает планируемую наработку и вызывается из задачи закрытия статуса, выполняется примерно две минуты.
Проблема: если абонент оплачивает услугу после окончания задачи "Calculator" и до окончания основной задачи закрытия статусов, то договор оказывается в статусе "Закрыт", не смотря на то, что баланс у него положительный.
Выдержка из логов поясняет (надеюсь) проблему.
Код:
...
03-01/01:10:02 INFO [Thread-4] TaskExecuter - Starting periodic task #27: ru.bitel.bgbilling.modules.npay.server.task.DebetStatusManageLocker
..
03-01/01:11:22 INFO [pool-2-thread-98] Calculator - Task finished time=80039 ms.
...
03-01/01:15:45 - здесь произошёл приход платежа, который сделал баланс на договоре больше нуля.
...
03-01/01:16:54 - здесь изменился статус договора на "Закрыт".
...
03-01/01:17:46 INFO [pool-2-thread-98] DebetStatusManageLocker - Task finished time=464490 ms.
...
Т. е. калькулятор посмотрел на баланс договора и понял, что договор нужно закрыть, и начал обрабатывать другие договоры. В это время абонент пополнил баланс и баланс стал положительным. Договор уже закрывать не нужно, но калькулятор уже всё посчитал. Когда доходит очередь до упомянутого договора, он закрывается не смотря на новый баланс.
Есть ли способ победить описанную проблему?
Пока вижу такое решение: выбирать неправильно закрытые договоры и отправлять им событие обновление баланса. Делать это после задачи закрытия договоров по балансу. Т. к. пока не понятно, как выбирать неправильно закрытые договоры, то можно просто рассылать события для всех закрытых договоров. Но это костыль, хочется нормального решения.
Нормально было бы получать список всех договоров и для каждого договора проверять текущий баланс и сразу закрывать его при необходимости. Уже этого будет достаточно.