t8y2/dbx · error
begin manual transaction: %w
Error message
begin manual transaction: %w
What it means
After successfully reserving an exclusive connection, the driver starts the actual database transaction with conn.BeginTx. If Oracle rejects the begin (connection already broken, session terminated, driver error), the reserved connection is closed and this wrapped error is returned. The manual transaction is therefore not started.
Source
Thrown at agents/drivers/oracle-go/main.go:1204
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 {
if s.manualTx == nil {
return errors.New("no manual transaction open")
}
err := s.manualTx.Commit()
s.clearManualTransaction()
return err
}
func (s *server) rollbackManualTransaction() error {
if s.manualTx == nil {
return errors.New("no manual transaction open")View on GitHub (pinned to c0390bff16)
Solutions
- Retry the whole beginManualTransaction operation (pool will hand out a fresh connection)
- Check for ORA- errors in the wrapped cause (e.g. ORA-00028 session killed, ORA-03113 end-of-file) and address per Oracle docs
- Enable connection lifetime/max-idle tuning so stale connections are culled before reuse
- Verify network stability between the driver host and the Oracle instance
Example fix
// before
tx, err := conn.BeginTx(ctx, nil) // stale conn -> ORA-03113
// after
for attempt := 0; attempt < 2; attempt++ {
if err := beginManualTransaction(s, schema); err == nil { break }
time.Sleep(500 * time.Millisecond) // retry gets a fresh pooled conn
} Defensive patterns
Strategy: retry
Validate before calling
if err := db.PingContext(ctx); err != nil { return err } // ensure pool conns are healthy before reserve+begin Try / catch
err := beginManualTransaction(s, schema)
if err != nil && strings.Contains(err.Error(), "begin manual transaction") {
time.Sleep(250 * time.Millisecond)
err = beginManualTransaction(s, schema) // retry gets a fresh pooled conn
} Prevention
- Set ConnMaxLifetime below firewall/NAT idle timeouts so stale conns are culled
- Retry reserve+begin as one unit — a reserved conn is closed on failure
- Watch for ORA-03113/ORA-00028 in wrapped errors to address root cause
- Begin the manual transaction promptly after reserving; avoid long gaps
When it happens
Trigger: Calling beginManualTransaction when the reserved connection was invalidated between db.Conn and BeginTx (network drop, server killed the session, idle timeout, driver.ErrBadConn), or an Oracle-side error preventing a new transaction on that session.
Common situations: Oracle session killed by a DBA or resource limit while the code runs; firewall/NAT dropping idle connections; begin called immediately after a reconnect where the pooled conn was stale.
Related errors
- reserve connection for manual transaction: %w
- failed to restore Oracle segment attributes: %w
- statements are required
- manual transaction already open
- no manual transaction open
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/32d63d8f38cb0809.
Report an issue: GitHub.