Skip to content

Run the single-statement deck writes at AUTOCOMMIT - #99

Merged
lesnik512 merged 1 commit into
mainfrom
perf/autocommit-single-statement-writes
Oct 17, 2026
Merged

lesnik512 merged 1 commit into
mainfrom
perf/autocommit-single-statement-writes

Conversation

@lesnik512

@lesnik512 lesnik512 commented Oct 17, 2026 •

Copy link
Copy Markdown
Member

POST /decks/ and PUT /decks/{id}/ each run one statement: INSERT ... ON CONFLICT ... RETURNING and UPDATE ... RETURNING. Wrapping a single statement in BEGIN and COMMIT only adds two round trips, because Postgres already runs a single statement atomically. Both use cases now take a new Database.autocommit_transaction, the pattern modern-python/chat-app#64 introduced for its single-statement reads.

How it works

  • autocommit_transaction is a db_retry.Transaction with isolation_level set to AUTOCOMMIT. The isolation level comes from its own provider, autocommit_isolation_level.
  • The asyncpg adapter's _start_transaction returns early at autocommit, so it sends no BEGIN, and commit() sends nothing when no transaction was started. Each write is now one round trip instead of three.
  • The use cases keep their async with self.transaction: block, so postgres_retry recovery is unchanged. A retry after a lost connection is safe. Create is idempotent on its key, and update writes the same values again.
  • UpdateCardsUseCase keeps the normal transaction. It raises NotFoundError after the UPDATE when fewer rows come back, and it needs the rollback to undo the rows that did match.

Tests

  • tests/test_autocommit_writes.py runs both use cases against a real primary engine. It checks that asyncpg reports no open transaction while the statement runs. Both tests failed before the DI change. The create test deletes its deck afterwards, because an autocommit write can't be rolled back. The update test uses a missing id, so it writes nothing.
  • The db_session fixture overrides autocommit_isolation_level to None. Switching the shared test connection to AUTOCOMMIT would roll back the outer test transaction, as in chat-app.
  • just test passes 80 tests at 100% coverage. just lint is clean.

POST /decks and PUT /decks/{id} each send one statement, so a BEGIN and COMMIT around it only add two round trips. They now use an AUTOCOMMIT Transaction, the same pattern chat-app uses for its single-statement reads.
@lesnik512
lesnik512 merged commit 9647751 into main Oct 17, 2026
3 checks passed
@lesnik512
lesnik512 deleted the perf/autocommit-single-statement-writes branch October 17, 2026 12:39
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.

1 participant