Skip to content

Finalize connection initialization transactions - #776

Merged
mdipierro merged 1 commit into
web2py:masterfrom
auden-rovellequartz:fix/finalize-connection-initialization
Sep 12, 2026
Merged

mdipierro merged 1 commit into
web2py:masterfrom
auden-rovellequartz:fix/finalize-connection-initialization

Conversation

@auden-rovellequartz

Copy link
Copy Markdown
Contributor

Problem

ConnectionPool.set_connection() runs new-connection hooks and an optional
liveness query, commonly SELECT 1;, but does not finalize the transaction
those operations can start when DB-API autocommit is disabled.

This is observable with PostgreSQL when a long-lived process initializes DAL at
module-import or worker-startup time, outside a request lifecycle. Because no
request teardown follows, pg_stat_activity can show that connection as
idle in transaction indefinitely, with SELECT 1; as its last query.

The behavior was diagnosed in a persistent OVXS deployment by Auden
RovelleQuartz of Omnia Value Exchange Systems.

Change

After the connection hooks and optional active-connection check complete
successfully, set_connection() now commits the resulting initialization
transaction when either the hooks ran or the active check was performed.

This gives connection acquisition an explicit transaction boundary for:

  • newly opened connections; and
  • pooled connections checked before reuse.

Why commit

A rollback could undo SQL-based session configuration performed by
after_connection hooks. Committing, rather than rolling back, preserves
successful initialization while ending the implicit transaction.

This occurs before the connection is returned to application code, so no
caller-owned transaction exists at this boundary.

If both connection hooks and active checking are disabled, set_connection()
does not add a commit.

Tests

The regression tests model transaction state and cover:

  • fresh connections;
  • pooled connection checkouts; and
  • connection hooks when active checking is disabled.

Validation performed against upstream commit
6fd518e09ac4fcf64408abb2259222251c870356:

  • Focused regression suite: 3 tests passed
  • Complete suite on Linux: 400 tests passed, 11 skipped
  • Complete suite on Windows with Python 3.13: 400 tests passed, 12 skipped
  • Ruff code check: passed
  • Ruff format check: passed
  • Python compilation: passed
  • Git whitespace validation: passed

Reproduction outline

  1. Configure a PostgreSQL DAL connection with DB-API autocommit disabled.
  2. Initialize DAL in a persistent process without entering a normal web-request lifecycle.
  3. Do not issue an application query or invoke DAL request cleanup.
  4. Inspect the connection from another PostgreSQL session using pg_stat_activity.

Before this change, the initialized backend can remain idle in transaction,
with the connection-test query as its last statement. After this change, the
backend is idle with no open transaction.

Connection hooks and the active-connection probe can implicitly begin a transaction when DB-API autocommit is disabled. Commit successful connection initialization before returning fresh or pooled connections so PostgreSQL does not retain otherwise unused backends as idle in transaction.

Committing preserves successful SQL-based session configuration performed by connection hooks, whereas rolling back could undo that initialization work. Add regression coverage for fresh connections, pooled checkouts, and configurations with active connection checks disabled.
@mdipierro
mdipierro merged commit dcf7674 into web2py:master Sep 12, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants