How avito-tech/go-transaction-manager works
1. What this repository is
- This is a multi-module Go library for transaction management, not an application.
- The root repo contains the shared orchestration layer plus a set of database-specific driver adapters.
- go.work ties the modules together for local development and testing.
2. Core abstraction layer: trm
- trm/ is the central package that defines the transaction-manager API, context propagation, and manager behavior.
- It is the boundary that application code depends on: repositories receive a context.Context, and transaction state is carried through that context.
- Key responsibilities include transaction lifecycle coordination, settings, error handling, and nested transaction chaining.
3. Transaction orchestration flow
- Application code calls a manager, typically through manager.Do(...).
- The manager starts or reuses a transaction, injects it into context, executes user code, then commits or rolls back based on the result.
- Repository methods do not need to know whether they are running inside a transaction; they resolve the active transaction from context or fall back to the base connection.
4. Context as the integration boundary
- The trm/context package defines the keys and helpers used to store transaction-related values in context.Context.
- Driver packages provide their own context getters so repositories can retrieve the correct transaction object for that backend.
- This design makes the transaction manager backend-agnostic while keeping context lookup consistent.
5. Driver packages: backend adapters
- drivers/ contains one module per supported backend:
- sql for database/sql
- sqlx for jmoiron/sqlx
- gorm for GORM
- mongo for the MongoDB Go driver
- goredis8 for go-redis
- pgxv4 and pgxv5 for pgx
- Each driver wraps the backend’s native transaction/session type and adapts it to the shared manager contracts.
- This is the main extensibility boundary: adding another database means adding another driver module, not changing the core manager.
6. Common driver pattern
- Most drivers contain:
- a factory that creates a transaction manager for that backend,
- context helpers to extract the current transaction,
- transaction logic for commit/rollback semantics,
- settings for backend-specific behavior.
- The contract.go files in some drivers define the interface expected from the underlying DB/session implementation.
7. Nested transactions and special cases
- The repository supports nested transaction behavior, but the mechanism varies by backend.
- For SQL-based drivers, nested behavior can use savepoints; drivers/sql/mock/savepoint.go and drivers/sql/savepoint.go show this concern explicitly.
- The root README also calls out ChainedMW for coordinating nested transactions across different managers, which matters when one service operation touches multiple databases.
8. Repository usage model
- The intended consumer pattern is “repository + context + manager.”
- Repositories are written against a DB handle plus a driver-specific context getter; they select either the active transaction or the base DB connection from context.
- This keeps business logic clean and makes transaction boundaries a caller concern rather than a repository concern.
9. Testing and verification structure
- Each driver module has focused unit tests, goroutine-leak tests, and some integration tests where the backend requires a real database.
- The trm/drivers/test package provides shared test infrastructure, including Docker Compose for database-backed integration runs.
- The repo also includes example tests in each driver module, which double as executable documentation for the supported usage patterns.
10. Internal benchmarks and research tooling
- trm/internal/benchmark/ contains performance investigations comparing context storage strategies and measuring the overhead of transaction management.
- These benchmarks are not runtime dependencies, but they explain design choices around context usage and overhead.
- trm/internal/prove_receiving_updates_without_vulnerabilities and trm/internal/recover_defer look like focused correctness experiments around Go runtime behavior and error/recovery semantics.
11. Code generation and support scripts
- trm/internal/codegen/redis suggests some generated support for Redis-related driver behavior.
- The sh/ directory contains repo automation for formatting, linting, dependency management, and release/tagging.
- CI is driven by GitHub Actions, with linting and multi-version Go test coverage wired through .github/workflows/main.yaml.
12. Infrastructure and external dependencies
- The library is built around external persistence systems rather than in-process storage: SQL databases, MongoDB, Redis, and PostgreSQL via pgx.
- Compatibility across multiple Go versions is a deliberate architectural constraint, which is why each module has its own go.mod and why the repo keeps older dependency versions in some modules.
- The architecture is therefore “core abstraction + backend adapters + context propagation,” optimized for reuse across many storage technologies.
13. How to draw the diagram
- Put trm in the center as the orchestration core.
- Show application/repository code calling into the manager with a context.
- Show driver modules as adapters between the core and backend-specific clients.
- Show context as the shared channel connecting manager and repositories.
- Show testing/benchmarking as parallel supporting subsystems, not part of the runtime path.
Main entry points: manager Manager · context Context · main.yaml Automation · go.work Go work
Components 18
Core
Shared transaction-manager API, context propagation, and orchestration.
- TRM · Public transaction-manager abstraction and shared entrypoint package.
trm - Context · Shared context keys and helpers for storing and retrieving transaction state.
trm/context - Manager · Transaction lifecycle coordination, reuse, commit, rollback, and chaining.
trm/manager - Settings · Core transaction-manager options and defaults.
trm/settings
Drivers
Backend adapters that wrap native DB/session transactions.
- SQL · database/sql backend adapter with savepoint support for nested transactions.
drivers/sql - SQLX · sqlx backend adapter built on the shared manager contracts.
drivers/sqlx - GORM · GORM backend adapter wrapping ORM transactions.
drivers/gorm - MongoDB · MongoDB backend adapter for session and transaction handling.
drivers/mongo - pgx v4 · pgx v4 adapter for PostgreSQL transactions.
drivers/pgxv4 - pgx v5 · pgx v5 adapter for PostgreSQL transactions.
drivers/pgxv5 - Redis · go-redis v8 adapter for transactional Redis workflows.
drivers/goredis8
Support
Testing, benchmarks, experiments, and repo automation.
- Test infra · Cross-driver test utilities, Docker Compose setup, and mock implementations.
trm/drivers/test - Benchmarks · Performance experiments for context storage and transaction overhead.
trm/internal/benchmark - Experiments · Focused proof and recovery experiments around Go behavior and error handling.
trm/internal/prove_receiving_updates_without_vulnerabilities - Codegen · Internal generation support for backend-specific helpers.
trm/internal/codegen/redis - Automation · Formatting, linting, testing, release scripts, and GitHub Actions workflows.
.github/workflows/main.yaml - Go work · Workspace file tying the repository modules together for local development.
go.work
Other components
- Repos · Application repositories and services that call into the manager with a context.
Connections 47
- Repos → Manager: Do / use · Repositories call the manager with a context and business function.
- Repos → Context: ctx lookup · Repositories resolve the active transaction from context.
- TRM → Manager: hosts · The root package exposes manager-oriented transaction APIs.
- TRM → Context: defines · Shared context keys and helpers live under the context boundary.
- TRM → Settings: configures · Core settings shape transaction behavior and defaults.
- Manager → Context: injects · Manager writes transaction state into context for downstream use.
- Manager → Settings: reads · Manager behavior is driven by core settings.
- Manager → SQL: adapts via · Manager coordinates SQL backend transactions through driver adapters.
- Manager → SQLX: adapts via · Manager coordinates sqlx backend transactions through driver adapters.
- Manager → GORM: adapts via · Manager coordinates GORM backend transactions through driver adapters.
- Manager → MongoDB: adapts via · Manager coordinates MongoDB backend sessions and transactions through driver adapters.
- Manager → pgx v4: adapts via · Manager coordinates pgx v4 backend transactions through driver adapters.
- Manager → pgx v5: adapts via · Manager coordinates pgx v5 backend transactions through driver adapters.
- Manager → Redis: adapts via · Manager coordinates Redis transactional behavior through driver adapters.
- SQL → Context: reads · SQL repositories and helpers extract transaction state from context.
- SQLX → Context: reads · SQLX repositories and helpers extract transaction state from context.
- GORM → Context: reads · GORM repositories and helpers extract transaction state from context.
- MongoDB → Context: reads · MongoDB repositories and helpers extract transaction state from context.
- pgx v4 → Context: reads · pgx v4 repositories and helpers extract transaction state from context.
- pgx v5 → Context: reads · pgx v5 repositories and helpers extract transaction state from context.
- Redis → Context: reads · Redis repositories and helpers extract transaction state from context.
- SQL → Test infra: verified by · SQL driver tests share backend and cleanup infrastructure.
- SQLX → Test infra: verified by · SQLX driver tests share backend and cleanup infrastructure.
- GORM → Test infra: verified by · GORM driver tests share backend and cleanup infrastructure.
- MongoDB → Test infra: verified by · MongoDB driver tests share backend and cleanup infrastructure.
- pgx v4 → Test infra: verified by · pgx v4 driver tests share backend and cleanup infrastructure.
- pgx v5 → Test infra: verified by · pgx v5 driver tests share backend and cleanup infrastructure.
- Redis → Test infra: verified by · Redis driver tests share backend and cleanup infrastructure.
- TRM → Benchmarks: studied by · Benchmarks explain context and manager overhead tradeoffs.
- TRM → Experiments: studied by · Internal experiments probe correctness and recovery behavior.
- Redis → Codegen: supported by · Redis driver support includes internal generated helpers.
- Automation → TRM: builds/tests · CI and scripts format, lint, and test the core module.
- Automation → SQL: builds/tests · CI and scripts format, lint, and test the SQL driver.
- Automation → SQLX: builds/tests · CI and scripts format, lint, and test the SQLX driver.
- Automation → GORM: builds/tests · CI and scripts format, lint, and test the GORM driver.
- Automation → MongoDB: builds/tests · CI and scripts format, lint, and test the Mongo driver.
- Automation → pgx v4: builds/tests · CI and scripts format, lint, and test the pgx v4 driver.
- Automation → pgx v5: builds/tests · CI and scripts format, lint, and test the pgx v5 driver.
- Automation → Redis: builds/tests · CI and scripts format, lint, and test the Redis driver.
- Go work → TRM: ties together · Workspace links the core module for local development.
- Go work → SQL: ties together · Workspace links the SQL driver module for local development.
- Go work → SQLX: ties together · Workspace links the SQLX driver module for local development.
- Go work → GORM: ties together · Workspace links the GORM driver module for local development.
- Go work → MongoDB: ties together · Workspace links the Mongo driver module for local development.
- Go work → pgx v4: ties together · Workspace links the pgx v4 driver module for local development.
- Go work → pgx v5: ties together · Workspace links the pgx v5 driver module for local development.
- Go work → Redis: ties together · Workspace links the Redis driver module for local development.