fix(pzz_loader): SAVEPOINT pattern + outer error handler (transaction correctness) #124

Merged
lekss361 merged 1 commit from fix/pzz-loader-savepoint into main 2026-05-14 20:29:23 +00:00

View file

@ -80,6 +80,10 @@ def sync_pzz_zones_to_db() -> dict[str, int]:
"""Загрузить зоны из PKK6 и UPSERT в pzz_zones_ekb. """Загрузить зоны из PKK6 и UPSERT в pzz_zones_ekb.
Возвращает словарь {fetched, inserted, updated, skipped}. Возвращает словарь {fetched, inserted, updated, skipped}.
Каждый UPSERT обёрнут в SAVEPOINT (db.begin_nested), чтобы ошибка
одной записи не откатывала всю транзакцию и счётчики оставались
согласованными с тем, что реально записано в DB.
""" """
features = asyncio.run(fetch_pkk6_zones()) features = asyncio.run(fetch_pkk6_zones())
inserted = 0 inserted = 0
@ -105,6 +109,7 @@ def sync_pzz_zones_to_db() -> dict[str, int]:
) )
description = props.get("description") description = props.get("description")
try: try:
with db.begin_nested(): # SAVEPOINT — откат только этой записи
result = db.execute( result = db.execute(
text(""" text("""
INSERT INTO pzz_zones_ekb INSERT INTO pzz_zones_ekb
@ -137,9 +142,12 @@ def sync_pzz_zones_to_db() -> dict[str, int]:
updated += 1 updated += 1
except Exception as e: except Exception as e:
logger.warning("PZZ insert failed for rosreestr_id=%s: %s", rosreestr_id, e) logger.warning("PZZ insert failed for rosreestr_id=%s: %s", rosreestr_id, e)
db.rollback()
skipped += 1 skipped += 1
db.commit() db.commit()
except Exception as e:
db.rollback()
logger.exception("pzz_loader: unexpected error, outer tx rolled back: %s", e)
raise
finally: finally:
db.close() db.close()
return { return {