Problem
Rails 7.2+ changed connection checkout semantics (per-request check-in via the executor). A Session that doesn't pin a connection can have its connection returned to the pool mid-block, which invalidates temp tables on Postgres.
Proposal
Wrap the session body in ActiveRecord::Base.connection_pool.with_connection { ... } (or the source_model's pool), pinning the connection for the duration of the block.
StagingTable.stage(User) do |staging| # automatic with_connection
staging.insert(rows)
end
Opt-out for advanced users who manage their own connection lifecycle:
StagingTable.stage(User, pin_connection: false) { ... }
Acceptance criteria
- Default behavior pins the connection for the
stage { } block
- Manual-control API gets a
Session#with_pinned_connection equivalent
- Test: under a forced pool-check-in mid-block (simulate via executor), temp table survives
- README note on Rails 7.2+ behavior change and why pinning matters
Problem
Rails 7.2+ changed connection checkout semantics (per-request check-in via the executor). A
Sessionthat doesn't pin a connection can have its connection returned to the pool mid-block, which invalidates temp tables on Postgres.Proposal
Wrap the session body in
ActiveRecord::Base.connection_pool.with_connection { ... }(or the source_model's pool), pinning the connection for the duration of the block.Opt-out for advanced users who manage their own connection lifecycle:
Acceptance criteria
stage { }blockSession#with_pinned_connectionequivalent