defmodule Mv.Repo.Migrations.MakeMemberUserFksDeferrable do @moduledoc """ Makes the members/users foreign keys DEFERRABLE INITIALLY DEFERRED. Concurrent `create_member` transactions take FK `FOR KEY SHARE` (MultiXact) locks on these foreign keys at statement time and can form a cross-transaction lock cycle, producing a PostgreSQL `deadlock_detected` (40P01). Deferring the FK checks to commit time breaks the cycle. Constraint deferrability is not tracked by AshPostgres resource snapshots, so this is a hand-written migration with raw `execute/2`. Do not regenerate it via `mix ash_postgres.generate_migrations`. """ use Ecto.Migration def change do execute( "ALTER TABLE users ALTER CONSTRAINT users_member_id_fkey DEFERRABLE INITIALLY DEFERRED", "ALTER TABLE users ALTER CONSTRAINT users_member_id_fkey NOT DEFERRABLE" ) execute( "ALTER TABLE users ALTER CONSTRAINT users_role_id_fkey DEFERRABLE INITIALLY DEFERRED", "ALTER TABLE users ALTER CONSTRAINT users_role_id_fkey NOT DEFERRABLE" ) execute( "ALTER TABLE members ALTER CONSTRAINT members_membership_fee_type_id_fkey DEFERRABLE INITIALLY DEFERRED", "ALTER TABLE members ALTER CONSTRAINT members_membership_fee_type_id_fkey NOT DEFERRABLE" ) end end