# ADR-002: No Context on Tx.Commit and Tx.Rollback **Status:** Accepted **Date:** 2026-03-18 ## Context The `postgres` module's `Tx` interface defines `Commit(ctx context.Context) error` and `Rollback(ctx context.Context) error` because `pgx.Tx` supports context-aware commit and rollback — the operation can be cancelled if the context is already done. The `database/sql` standard library's `*sql.Tx` does not support this. Its `Commit()` and `Rollback()` methods have no context parameter: ```go // from database/sql: func (tx *Tx) Commit() error func (tx *Tx) Rollback() error ``` Adding a `ctx` parameter to the `mysql.Tx` interface would be a lie: the implementation would have to ignore the context, potentially masking cancellations or deadlines that callers believe they are enforcing. ## Decision The `mysql.Tx` interface is defined with context-free commit and rollback, matching the `database/sql` contract honestly: ```go type Tx interface { Executor Commit() error Rollback() error } ``` The `UnitOfWork.Do` implementation calls `tx.Rollback()` and `tx.Commit()` without passing a context. This is consistent with the interface definition and with `database/sql` semantics. This means `mysql.Tx` and `postgres.Tx` are not structurally compatible — this is intentional. Callers must not attempt to use one in place of the other. ## Consequences - **Positive**: The interface is an honest representation of what `database/sql` provides. No silent context-ignore bugs. - **Positive**: `mysqlTx.Commit()` and `mysqlTx.Rollback()` delegate directly to `*sql.Tx.Commit()` and `*sql.Tx.Rollback()` with no wrapper complexity. - **Negative**: A commit or rollback cannot be cancelled mid-flight via context in MySQL. If the database is slow or unreachable during commit, the goroutine blocks until the driver-level timeout fires. - **Negative**: The API asymmetry between `mysql.Tx` and `postgres.Tx` means that generic code written against one cannot be used against the other. This is a known limitation of the design and the reason the two modules are separate. - **Note**: Go 1.15 added `*sql.Tx.Commit()` and `*sql.Tx.Rollback()` that honour the context passed to `BeginTx` — but still do not accept a per-call context. The limitation is inherent to `database/sql`.