{"record":{"id":"81340d3b8f401e1f","repo":"t8y2/dbx","slug":"reserve-connection-for-manual-transaction-w","errorCode":null,"errorMessage":"reserve connection for manual transaction: %w","messagePattern":"reserve connection for manual transaction: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/oracle-go/main.go","lineNumber":1193,"sourceCode":"\t}\n\terr := s.db.Close()\n\ts.db = nil\n\treturn err\n}\n\nfunc (s *server) beginManualTransaction(schema string) error {\n\tif s.manualTx != nil {\n\t\treturn errors.New(\"manual transaction already open\")\n\t}\n\tdb, err := s.requireDB()\n\tif err != nil {\n\t\treturn err\n\t}\n\t// Hold one exclusive physical connection so DML/SELECT/schema stay on the\n\t// same Oracle session for the life of the interactive transaction.\n\tconn, err := db.Conn(context.Background())\n\tif err != nil {\n\t\treturn fmt.Errorf(\"reserve connection for manual transaction: %w\", err)\n\t}\n\tif strings.TrimSpace(schema) != \"\" {\n\t\tif _, err := conn.ExecContext(context.Background(), \"ALTER SESSION SET CURRENT_SCHEMA = \"+quoteIdentifier(schema)); err != nil {\n\t\t\t_ = conn.Close()\n\t\t\treturn err\n\t\t}\n\t}\n\ttx, err := conn.BeginTx(context.Background(), nil)\n\tif err != nil {\n\t\t_ = conn.Close()\n\t\treturn fmt.Errorf(\"begin manual transaction: %w\", err)\n\t}\n\ts.manualConn = conn\n\ts.manualTx = tx\n\treturn nil\n}\n\nfunc (s *server) commitManualTransaction() error {","sourceCodeStart":1175,"sourceCodeEnd":1211,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/oracle-go/main.go#L1175-L1211","documentation":"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'.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check DB reachability and listener status (tnsping / test a plain db.Ping) to rule out network issues","Increase the pool size (SetMaxOpenConns) or release idle connections so one can be reserved exclusively","Ensure the sql.DB is not closed before beginManualTransaction is invoked","Retry with backoff if the failure was transient pool exhaustion"],"exampleFix":"// before\ndb.SetMaxOpenConns(1) // other work holds the only conn\n// after\ndb.SetMaxOpenConns(10) // headroom so the manual tx can reserve a conn","handlingStrategy":"retry","validationCode":"if err := db.PingContext(ctx); err != nil { return fmt.Errorf(\"db unreachable before manual tx: %w\", err) }\nif db.Stats().OpenConnections >= maxOpen { return errors.New(\"pool saturated; cannot reserve conn\") }","typeGuard":null,"tryCatchPattern":"var conn *sql.Conn\nfor i := 0; i < 3; i++ {\n    err := beginManualTransaction(s, schema)\n    if err == nil { break }\n    if strings.Contains(err.Error(), \"reserve connection for manual transaction\") {\n        time.Sleep(time.Duration(1<<i) * 100 * time.Millisecond)\n        continue\n    }\n    return err\n}\n_ = conn","preventionTips":["Size the pool with headroom (SetMaxOpenConns > concurrent manual txs)","Ping or health-check the DB before starting interactive transactions","Avoid closing the pool while a manual transaction may begin","Use context timeouts so reserve attempts fail fast rather than hang"],"tags":["go","oracle","connection-pool","transaction"],"backgroundTag":"connection-pool-exhausted","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}