t8y2/dbx · error

reserve connection for manual transaction: %w

Error message

reserve connection for manual transaction: %w

What it means

To make DML/SELECT/schema changes stay on one Oracle session for the life of a manual (interactive) transaction, the driver reserves one exclusive physical connection via db.Conn. If the pool cannot hand out a connection (context canceled, pool exhausted/closed, driver/network failure), the error is wrapped as 'reserve connection for manual transaction'.

Source

Thrown at agents/drivers/oracle-go/main.go:1193

	}
	err := s.db.Close()
	s.db = nil
	return err
}

func (s *server) beginManualTransaction(schema string) error {
	if s.manualTx != nil {
		return errors.New("manual transaction already open")
	}
	db, err := s.requireDB()
	if err != nil {
		return err
	}
	// Hold one exclusive physical connection so DML/SELECT/schema stay on the
	// same Oracle session for the life of the interactive transaction.
	conn, err := db.Conn(context.Background())
	if err != nil {
		return fmt.Errorf("reserve connection for manual transaction: %w", err)
	}
	if strings.TrimSpace(schema) != "" {
		if _, err := conn.ExecContext(context.Background(), "ALTER SESSION SET CURRENT_SCHEMA = "+quoteIdentifier(schema)); err != nil {
			_ = conn.Close()
			return err
		}
	}
	tx, err := conn.BeginTx(context.Background(), nil)
	if err != nil {
		_ = conn.Close()
		return fmt.Errorf("begin manual transaction: %w", err)
	}
	s.manualConn = conn
	s.manualTx = tx
	return nil
}

func (s *server) commitManualTransaction() error {

View on GitHub (pinned to c0390bff16)

Solutions

  1. Check DB reachability and listener status (tnsping / test a plain db.Ping) to rule out network issues
  2. Increase the pool size (SetMaxOpenConns) or release idle connections so one can be reserved exclusively
  3. Ensure the sql.DB is not closed before beginManualTransaction is invoked
  4. Retry with backoff if the failure was transient pool exhaustion

Example fix

// before
db.SetMaxOpenConns(1) // other work holds the only conn
// after
db.SetMaxOpenConns(10) // headroom so the manual tx can reserve a conn
Defensive patterns

Strategy: retry

Validate before calling

if err := db.PingContext(ctx); err != nil { return fmt.Errorf("db unreachable before manual tx: %w", err) }
if db.Stats().OpenConnections >= maxOpen { return errors.New("pool saturated; cannot reserve conn") }

Try / catch

var conn *sql.Conn
for i := 0; i < 3; i++ {
    err := beginManualTransaction(s, schema)
    if err == nil { break }
    if strings.Contains(err.Error(), "reserve connection for manual transaction") {
        time.Sleep(time.Duration(1<<i) * 100 * time.Millisecond)
        continue
    }
    return err
}
_ = conn

Prevention

When it happens

Trigger: Calling beginManualTransaction (with a schema) when the database pool is exhausted by other in-flight work, the DB is unreachable, database/sql max open connections is 0/maxed out, or the pool was closed before this call.

Common situations: Long-running interactive transaction started while background queries saturate the connection pool; network/tns errors to the Oracle instance; SetMaxOpenConns set too low; connection pooling misconfiguration.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/81340d3b8f401e1f. Report an issue: GitHub.