Avoid transaction-poisoning DDL and harden multi-pod races

FixSecurityService
Shipped
April 20, 2026 at 8:43 PM UTC
Author
Kamo
Commit
d3249b4

The previous self-heal put DDL inside a @Transactional syncAll(). When an ALTER TABLE ADD CONSTRAINT fired on an existing constraint (normal case after first boot, or the losing pod in a multi-pod race), runIdempotent swallowed the Java exception — but the surrounding DB transaction was left in an aborted state. Every subsequent JPA call then hit `current transaction is aborted, commands ignored until end of transaction block`, taking the pod down on every restart. Changes: - syncAll() is no longer @Transactional. Each phase runs with its own autonomy: DDL auto-commits per statement outside any Spring TX, so a single-statement failure cannot poison anything. - ensureUniqueConstraint() now checks pg_constraint before attempting ADD, so the "already exists" error never fires on normal restarts. - Self-injection (@Lazy self) so the sub-methods' @Transactional actually fires via the Spring proxy (the previous this.syncOrgRoleRights() call bypassed AOP). - Documented the concurrent-pod race analysis: DDL serialized by CRDB, DELETEs idempotent, inserts race-safe via ON CONFLICT DO NOTHING.

All changes

Like what you see shipping?

Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.

Start Free ForeverView Pricing