fix(tradein/matching): listing_sources датируется построчно, а не стартом транзакции (#2731) #2743
No reviewers
Labels
No labels
Fable 5 ревью
GG-форсайт
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
feedback/max
generative
needs-discussion
needs-human
observability
pause-bots
performance
priority/p0
priority/p1
priority/p2
priority/p3
scope/backend
scope/db
scope/devops
scope/frontend
scope/qa
scrapers
security
site-finder
stage/1
stage/2
status/blocked
status/done
status/needs-analysis
status/needs-fix
status/qa
status/ready
status/review
status/wip
tech-debt
tradein
ux
week ревью 1
wontfix
ИРД
вторичка
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#2743
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/2731-listing-sources-clock"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Что
Вторая половина #2731 (первая — PR #2742).
_upsert_listing_sourceвызывается ПОСТРОЧНО изsave_listings(hook_link_listing_to_house), а транзакция batch'а коммитится один раз в конце — значитNOW()==transaction_timestamp()давал одну метку на весь вызов.Прод-замер 2026-08-06,
listing_sourcesпо часам (строк / различных меток):last_seen_atиlast_scraped_atсхлопнуты одинаково и равны друг другу у 100% строк.Почему это НЕ отдельная правка, а обязательное продолжение #2742
Сегодня
listings.last_seen_at = listing_sources.last_seen_atу 2407 пар из 2407 за сутки — ровно потому, что обе колонки берут одну транзакционную метку. Если оставить эту половину наNOW(), то после #2742 первая колонка станет построчной, а вторая останется замороженной на старте batch'а: расхождение выросло бы с миллисекунд (честная разница двух соседних записей) до длительности прогона — то есть на месте одного дефекта появился бы другой.Потребителя, сравнивающего эти две колонки между таблицами, в коде нет (проверено grep'ом) — но систематически смещённая колонка хуже честно разъехавшейся на миллисекунды.
Согласованность внутри строки
matched_at/last_seen_at/last_scraped_atпишутся ОДНИМ statement'ом →statement_timestamp()даёт им одинаковое значение, их равенство сохранено.clock_timestamp()развёл бы их на микросекунды (прод:clock_timestamp() = clock_timestamp()→ false).Test plan
tests/test_2731_listing_sources_timestamps.py— писатель, отработавший дольше секунды, оставляет РАЗЛИЧНЫЕ метки; три отметки одного statement'а совпадаютNOW()) тест на различие меток падает (все три метки равны 0.0)test-job cancelled → деплой на старом образе)Refs #2731