ory/hydra · error
database error on committing or rolling back transaction: %w
Error message
database error on committing or rolling back transaction: %w
What it means
In popx's transaction wrapper, if Commit (success path) or Rollback (error path) itself fails with a database error other than the tolerated sql.ErrTxDone / 'conn closed' cases, the wrapper wraps that dberr in this message and returns it, obscuring but preserving the commit/rollback failure.
Source
Thrown at oryx/popx/transaction.go:118
err = callback(WithTransaction(ctx, cn), cn)
var dberr error
if err != nil {
dberr = cn.TX.Rollback()
if errors.Is(dberr, sql.ErrTxDone) {
// Already rolled back by the database (e.g. context cancelled).
return err
}
if dberr != nil && dberr.Error() == "conn closed" {
// pgx closes the connection on context cancellation before
// database/sql gets a chance to roll back.
// See https://github.com/jackc/pgx/issues/2551
return err
}
} else {
dberr = cn.TX.Commit()
}
if dberr != nil {
return fmt.Errorf("database error on committing or rolling back transaction: %w", dberr)
}
return err
}()
if err == nil || !errors.Is(sqlcon.HandleError(err), sqlcon.ErrConcurrentUpdate()) {
return err
}
}
return err
})
}
// SQLite and unknown dialects: opts are ignored; use pop's default
// transaction path with concurrent-update retry handling.
var err error
for attempt := range MaxTransactionRetries {
err = conn.Transaction(func(tx *pop.Connection) error {
return callback(WithTransaction(ctx, tx), tx)
})View on GitHub (pinned to 4174065ffb)
Solutions
- Check the wrapped %w cause for the underlying driver error (context canceled, connection reset, etc.)
- Retry the whole transaction operation — the wrapper already retries concurrent-update (40001) failures, but commit-time connection loss needs an application-level retry
- Reduce transaction duration and set appropriate statement/idle timeouts so the DB does not kill the connection mid-commit
- Ensure callers pass a context that stays alive until the transaction completes
- Inspect DB/proxy logs (PgBouncer, LB idle timeouts) for connection teardown at commit time
Example fix
// before
err := trx(ctx, conn, func(ctx context.Context, tx *pop.Connection) error { ... }) // one-shot, fails on commit drop
// after
for i := 0; i < 3; i++ {
if err := trx(ctx, conn, callback); err == nil || !isConnectionError(err) {
return err
}
time.Sleep(backoff(i))
} Defensive patterns
Strategy: retry
Validate before calling
func withinDeadline(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc, error) {
if ctx.Err() != nil {
return nil, nil, fmt.Errorf("context already cancelled before transaction: %w", ctx.Err())
}
return context.WithTimeout(ctx, d), nil, nil
} Try / catch
var err error
for attempt := 0; attempt < 3; attempt++ {
err = withTransaction(ctx, conn, callback)
if err == nil {
break
}
var dbErr interface{ Unwrap() error }
if !errors.As(err, &dbErr) || !isTransientConnError(errors.Unwrap(err)) {
break // permanent error, do not retry
}
time.Sleep(time.Duration(1<<attempt) * 100 * time.Millisecond)
} Prevention
- Keep transactions short so idle/statement timeouts cannot kill the connection before Commit
- Pass a live context — cancelled contexts race with Commit and produce conn-closed failures
- Check proxy/LB (PgBouncer, cloud LB) idle timeouts against your longest transactions
- Retry at the application level for transient connection errors; only 40001 is retried internally
- Monitor the wrapped cause (%w) in logs to distinguish commit vs rollback failures
When it happens
Trigger: Calling conn.WithTransaction-style wrapped transactions where the connection drops between the callback and Commit/Rollback; database restart or network cut mid-transaction; context cancellation racing with Commit; pgx connection closed unexpectedly.
Common situations: Long-running transactions hitting idle timeouts; Kubernetes killing connections during deploys; context deadlines expiring exactly at commit time; transient network blips with Postgres-compatible stores (CockroachDB, YugabyteDB).
Related errors
- unsupported dialect
- invalid DSN: missing scheme separator
- invalid DSN: empty scheme
- failed to acquire sql.Conn for restore
- problem checking for migration version %s
AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03).
Data as JSON: /api/errors/f1f1cc2bd985f698.
Report an issue: GitHub.