Согласен, по итогу мы примерно туда и пришли: выборка нужных колонок, значения в кортежах, bulk UPDATE. Фактически тот же SQL, просто через Core.
Мне кажется, водораздел проходит не между ORM и SQL, а между типами кода. В обычных ручках API объекты удобнее: транзакция короткая, сущность одна, читается лучше. А в фоновом проходе по всей базе, где чтение и запись вперемешку, ORM прячет цену. Причём прячет так, что заметно её только счётчиком запросов.
Окно, правда, узкое. Флаг ставится только если отправка реально прошла: вернулась ошибка, id в пачку не попал и уйдёт следующим тиком. И коммит не в конце всего прохода, а после каждого тренера. То есть при падении процесса теряется максимум пачка одного человека, обычно одно-три напоминания, а не половина рассылки.
Цена дубля тут небольшая, лишнее «через час тренировка». Пережить можно, поэтому сознательно живём с повтором.
А вот где нельзя, это деньги. Там механизм другой: атомарный UPDATE … SET applied = true WHERE applied = false и проверка, сколько строк реально обновилось. Начисляем, только если строка досталась нам. Повторная доставка вебхука на этом и гасится.
Согласен, по итогу мы примерно туда и пришли: выборка нужных колонок, значения в кортежах, bulk UPDATE. Фактически тот же SQL, просто через Core.
Мне кажется, водораздел проходит не между ORM и SQL, а между типами кода. В обычных ручках API объекты удобнее: транзакция короткая, сущность одна, читается лучше. А в фоновом проходе по всей базе, где чтение и запись вперемешку, ORM прячет цену. Причём прячет так, что заметно её только счётчиком запросов.
Да, всё так, это осознанный at-least-once.
Окно, правда, узкое. Флаг ставится только если отправка реально прошла: вернулась ошибка, id в пачку не попал и уйдёт следующим тиком. И коммит не в конце всего прохода, а после каждого тренера. То есть при падении процесса теряется максимум пачка одного человека, обычно одно-три напоминания, а не половина рассылки.
Цена дубля тут небольшая, лишнее «через час тренировка». Пережить можно, поэтому сознательно живём с повтором.
А вот где нельзя, это деньги. Там механизм другой: атомарный UPDATE … SET applied = true WHERE applied = false и проверка, сколько строк реально обновилось. Начисляем, только если строка досталась нам. Повторная доставка вебхука на этом и гасится.