Зачем: владелец пометил N13 как «не воспроизведено», а в коде окно гонки (SELECT ... FOR UPDATE по отсутствующей строке, затем INSERT ... ON CONFLICT DO NOTHING со своим runId) видно. Нужен повторяемый замер на живом сервере и реальной PostgreSQL 17, а не рассуждение. Что: scripts/test/n13-race.mjs — 10/25/50 параллельных первых POST /payroll/calculate, каждая попытка на новой точке, проверка статусов, числа run_id, строк в staff_payroll_runs и «фантомных» run_id. Режим as-is показывает, что сейчас всё упирается в N2 (500). Режим n2-bypass ставит DEFAULT now() только в одноразовой БД скрипта (продукт и миграции не меняются), чтобы увидеть саму гонку. Итог: 0 некорректных из 30 попыток; причина (из кода) — случайная сериализация через upsert ensureDefaultPayRules. Это записано в NOTES-FOR-EXECUTORS вместе с рекомендацией явной блокировки и замечанием об утечке текста ошибок БД в 500.
58 lines
8.5 KiB
Text
58 lines
8.5 KiB
Text
$ node scripts/test/n13-race.mjs --mode as-is --attempts 5
|
|
[n13] mode=as-is sessions=false N=10 attempt=1: statuses={"500":10} distinct_run_ids=0 db_runs=0 db_lines=0 phantom_run_ids=0 errors={"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint":10} -> BAD
|
|
[n13] mode=as-is sessions=false N=10 attempt=2: statuses={"500":10} distinct_run_ids=0 db_runs=0 db_lines=0 phantom_run_ids=0 errors={"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint":10} -> BAD
|
|
[n13] mode=as-is sessions=false N=10 attempt=3: statuses={"500":10} distinct_run_ids=0 db_runs=0 db_lines=0 phantom_run_ids=0 errors={"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint":10} -> BAD
|
|
[n13] mode=as-is sessions=false N=10 attempt=4: statuses={"500":10} distinct_run_ids=0 db_runs=0 db_lines=0 phantom_run_ids=0 errors={"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint":10} -> BAD
|
|
[n13] mode=as-is sessions=false N=10 attempt=5: statuses={"500":10} distinct_run_ids=0 db_runs=0 db_lines=0 phantom_run_ids=0 errors={"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint":10} -> BAD
|
|
[n13] mode=as-is sessions=false N=25 attempt=1: statuses={"500":25} distinct_run_ids=0 db_runs=0 db_lines=0 phantom_run_ids=0 errors={"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint":25} -> BAD
|
|
[n13] mode=as-is sessions=false N=25 attempt=2: statuses={"500":25} distinct_run_ids=0 db_runs=0 db_lines=0 phantom_run_ids=0 errors={"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint":25} -> BAD
|
|
[n13] mode=as-is sessions=false N=25 attempt=3: statuses={"500":25} distinct_run_ids=0 db_runs=0 db_lines=0 phantom_run_ids=0 errors={"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint":25} -> BAD
|
|
[n13] mode=as-is sessions=false N=25 attempt=4: statuses={"500":25} distinct_run_ids=0 db_runs=0 db_lines=0 phantom_run_ids=0 errors={"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint":25} -> BAD
|
|
[n13] mode=as-is sessions=false N=25 attempt=5: statuses={"500":25} distinct_run_ids=0 db_runs=0 db_lines=0 phantom_run_ids=0 errors={"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint":25} -> BAD
|
|
[n13] mode=as-is sessions=false N=50 attempt=1: statuses={"500":50} distinct_run_ids=0 db_runs=0 db_lines=0 phantom_run_ids=0 errors={"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint":50} -> BAD
|
|
[n13] mode=as-is sessions=false N=50 attempt=2: statuses={"500":50} distinct_run_ids=0 db_runs=0 db_lines=0 phantom_run_ids=0 errors={"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint":50} -> BAD
|
|
[n13] mode=as-is sessions=false N=50 attempt=3: statuses={"500":50} distinct_run_ids=0 db_runs=0 db_lines=0 phantom_run_ids=0 errors={"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint":50} -> BAD
|
|
[n13] mode=as-is sessions=false N=50 attempt=4: statuses={"500":50} distinct_run_ids=0 db_runs=0 db_lines=0 phantom_run_ids=0 errors={"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint":50} -> BAD
|
|
[n13] mode=as-is sessions=false N=50 attempt=5: statuses={"500":50} distinct_run_ids=0 db_runs=0 db_lines=0 phantom_run_ids=0 errors={"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint":50} -> BAD
|
|
[n13] ИТОГ mode=as-is sessions=false: попыток 15, некорректных 15
|
|
exit=1
|
|
|
|
$ node scripts/test/n13-race.mjs --mode n2-bypass --attempts 5
|
|
[n13] ДИАГНОСТИКА: staff_outbox.occurred_at DEFAULT now() (обход N2 только в этой БД)
|
|
[n13] mode=n2-bypass sessions=false N=10 attempt=1: statuses={"200":10} distinct_run_ids=1 db_runs=1 db_lines=0 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=false N=10 attempt=2: statuses={"200":10} distinct_run_ids=1 db_runs=1 db_lines=0 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=false N=10 attempt=3: statuses={"200":10} distinct_run_ids=1 db_runs=1 db_lines=0 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=false N=10 attempt=4: statuses={"200":10} distinct_run_ids=1 db_runs=1 db_lines=0 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=false N=10 attempt=5: statuses={"200":10} distinct_run_ids=1 db_runs=1 db_lines=0 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=false N=25 attempt=1: statuses={"200":25} distinct_run_ids=1 db_runs=1 db_lines=0 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=false N=25 attempt=2: statuses={"200":25} distinct_run_ids=1 db_runs=1 db_lines=0 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=false N=25 attempt=3: statuses={"200":25} distinct_run_ids=1 db_runs=1 db_lines=0 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=false N=25 attempt=4: statuses={"200":25} distinct_run_ids=1 db_runs=1 db_lines=0 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=false N=25 attempt=5: statuses={"200":25} distinct_run_ids=1 db_runs=1 db_lines=0 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=false N=50 attempt=1: statuses={"200":50} distinct_run_ids=1 db_runs=1 db_lines=0 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=false N=50 attempt=2: statuses={"200":50} distinct_run_ids=1 db_runs=1 db_lines=0 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=false N=50 attempt=3: statuses={"200":50} distinct_run_ids=1 db_runs=1 db_lines=0 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=false N=50 attempt=4: statuses={"200":50} distinct_run_ids=1 db_runs=1 db_lines=0 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=false N=50 attempt=5: statuses={"200":50} distinct_run_ids=1 db_runs=1 db_lines=0 phantom_run_ids=0 errors={} -> OK
|
|
[n13] ИТОГ mode=n2-bypass sessions=false: попыток 15, некорректных 0
|
|
exit=0
|
|
|
|
$ node scripts/test/n13-race.mjs --mode n2-bypass --attempts 5 --with-sessions --db krona_staff_n13_sessions
|
|
[n13] ДИАГНОСТИКА: staff_outbox.occurred_at DEFAULT now() (обход N2 только в этой БД)
|
|
[n13] mode=n2-bypass sessions=true N=10 attempt=1: statuses={"200":10} distinct_run_ids=1 db_runs=1 db_lines=1 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=true N=10 attempt=2: statuses={"200":10} distinct_run_ids=1 db_runs=1 db_lines=1 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=true N=10 attempt=3: statuses={"200":10} distinct_run_ids=1 db_runs=1 db_lines=1 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=true N=10 attempt=4: statuses={"200":10} distinct_run_ids=1 db_runs=1 db_lines=1 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=true N=10 attempt=5: statuses={"200":10} distinct_run_ids=1 db_runs=1 db_lines=1 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=true N=25 attempt=1: statuses={"200":25} distinct_run_ids=1 db_runs=1 db_lines=1 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=true N=25 attempt=2: statuses={"200":25} distinct_run_ids=1 db_runs=1 db_lines=1 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=true N=25 attempt=3: statuses={"200":25} distinct_run_ids=1 db_runs=1 db_lines=1 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=true N=25 attempt=4: statuses={"200":25} distinct_run_ids=1 db_runs=1 db_lines=1 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=true N=25 attempt=5: statuses={"200":25} distinct_run_ids=1 db_runs=1 db_lines=1 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=true N=50 attempt=1: statuses={"200":50} distinct_run_ids=1 db_runs=1 db_lines=1 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=true N=50 attempt=2: statuses={"200":50} distinct_run_ids=1 db_runs=1 db_lines=1 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=true N=50 attempt=3: statuses={"200":50} distinct_run_ids=1 db_runs=1 db_lines=1 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=true N=50 attempt=4: statuses={"200":50} distinct_run_ids=1 db_runs=1 db_lines=1 phantom_run_ids=0 errors={} -> OK
|
|
[n13] mode=n2-bypass sessions=true N=50 attempt=5: statuses={"200":50} distinct_run_ids=1 db_runs=1 db_lines=1 phantom_run_ids=0 errors={} -> OK
|
|
[n13] ИТОГ mode=n2-bypass sessions=true: попыток 15, некорректных 0
|
|
exit=0
|