Как реализовать ежечасное списание баланса пользователя?
На сайте имеется таблица users c полями: имя пользователя, пароль баланс и прочее.
У users есть связанная таблица services содержащая service_name, tarif, status, updated_at и прочее.
Если пользователь публикует услугу, то статус меняется на show и соответственно меняется время updated_at. Как при такой структуре организовать ежечасное списание средств с баланса пользователя согласно тарифу в таблице services? Вроде понятно, но допустим скрипт срабатывает каждый час в hh-часов:00-минут, а один из пользователей добавил услугу 2 минуты назад у него произойдет списание как за час.
Как вообще делают такие вещи, может что то нужно поменять в корне?
Не нужно привязываться к абсолютному времени. У каждого пользователя может быть свое время оплаты и сколько минут он может видеть контент (поесть 2 колонки, время оплаты, время истечения услуги). Далее раз в n минут проверяешь всех пользователей, у кого истек тариф, закрываешь услугу. Если скрипт не может осилить проход всех клиентов раз в минуту, увеличиваешь время и пишешь погрешность в тарифе.
Еще бы посоветовал не использовать одно поле "баланс", рано или поздно ты нарвёшься на дэдлоки, плюс очень вероятны ошибочные начисления. Лучше всего использовать систему дебета-кредита, где пишется вся история начисления или списания, а итоговую сумму в кошелке ты высчитываешь динамически.
В чем разница между балансом и историей? Если проставлены foreign keys с on update cascade/on delete cascade, мускул не даст вставить новую строку пока не разлочится апдейт юзера.
Разницы никакой вообще, только сложнее для разработки и обчисления мускулом.
Alex Wells, Эту разницу очень давно поняли бухгалтера, когда к ним приходит аудит налоговой и спрашивает откуда вы получили 1млн на счету =).
Если вкратце. такой подход поможет легко проследить историю всех транзакций клиента, сверить с реальным приходом денег на счет и тем что вам заявляет клиент через саппорт. Так же легко сможете сделать пересчет биллинга при неправильном начислении услуги. И обычно на 10 клиентов, которые просто требуют, один будет требовать с привлечением гос регулирования.
высчитываешь динамически
Неправильно выразился. Колонка "итого" в истории само-собой должна быть, но ее всегда можно будет динамически пересчитать.
В интернете есть много вариантов биллинг структуры, посмотрите на досуге, очень интересно.
Barmunk, Теперь что то проясняется в голове. На счет динамического вычисления, тоже сразу подумал именно о возможности пересчета. спасибо огромное за ответ.
Barmunk, конечно, я не спорю с тем, что это удобно и может быть нужно с точки зрения бизнеса. Я имел в виду только то, что дедлоки неизбежны, если код написан неправильно/не совсем правильно/без ретраев, независимо от того, используешь ты одно поле или табличку)