Database transaction opened without a deferred rollback
May 23, 2026 ยท View on GitHub
Playbook ID: missing-transaction-rollback
Category: runtime
Severity: high
Tags: source, go, database, transaction, sql, reliability
What this failure means
A database transaction is opened and committed in the same function with no
defer tx.Rollback() guard, so if an error path returns early the transaction
is silently left open, holding connections and locks.
Common log signals
(This playbook uses source-code pattern matching rather than log signals.)
Diagnosis
A db.Begin() or db.BeginTx() call is followed by tx.Commit() in the
same function, but there is no defer tx.Rollback() to release the
transaction on error paths.
The idiomatic Go pattern defers a rollback immediately after a successful
Begin:
tx, err := db.Begin()
if err != nil { return err }
defer tx.Rollback() // safe no-op if Commit already succeeded
Without the deferred rollback:
- Any early return on an error before
Commitleaves the transaction open until the database connection times out. - Under concurrent load, leaked transactions exhaust the connection pool.
- Table locks held by uncommitted transactions block other writers.
Fix steps
- Add
defer tx.Rollback()immediately after a successfulBegin:tx, err := db.BeginTx(ctx, nil) if err != nil { return fmt.Errorf("begin tx: %w", err) } defer tx.Rollback() // always deferred; no-op after a successful Commit // ... mutations ... return tx.Commit() - Return the error from
Commitso the caller knows if it failed. - Avoid capturing
txin a closure that may outlive the deferred rollback.
Validation
- Run
faultline inspect .from the repository root and confirm this source finding is absent or intentionally mitigated. - Test that an error on any path before
Commitreleases the connection cleanly without exhausting the pool.
Likely files to inspect
**/*.go
Run Faultline
faultline analyze build.log
faultline explain missing-transaction-rollback
faultline workflow build.log --json --mode agent
Search phrases this page answers
- Database transaction opened without a deferred rollback
- Runtime: database transaction opened without a deferred rollback
- faultline explain missing-transaction-rollback
- Go database transaction opened without a deferred rollback
Generated from playbooks/bundled/source/missing-transaction-rollback.yaml. Do not edit directly โ run make docs-generate.