Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 82 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,88 @@
package main

import "fmt"
import (
"context"
"database/sql/driver"
"errors"
"fmt"
)

// conn represents a physical MySQL connection.
type conn struct {
id int
closed bool
}

// BeginTx implements driver.ConnBeginTx.
//
// When the context is canceled during transaction initiation, the connection's
// transaction state is indeterminate — START TRANSACTION may have already been
// sent to the server. Returning only the context error causes database/sql to
// treat the connection as healthy and return it to the pool, where subsequent
// queries inherit the open transaction.
//
// By returning driver.ErrBadConn, we signal database/sql to discard this
// connection and open a fresh one, preventing connection pollution.
func (c *conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
// Simulate network roundtrip for START TRANSACTION
done := make(chan struct{})
var tx driver.Tx

go func() {
tx = &transaction{conn: c}
close(done)
}()

select {
case <-ctx.Done():
// Context canceled — transaction state is indeterminate.
// Attempt ROLLBACK to clean up server-side state. If ROLLBACK
// fails because the context is expired, discard the connection.
if err := c.rollback(ctx); err != nil {
return nil, driver.ErrBadConn
}
return nil, ctx.Err()
case <-done:
if err := ctx.Err(); err != nil {
c.rollback(context.Background())
return nil, driver.ErrBadConn
}
return tx, nil
}
}

// rollback attempts to roll back any active transaction on the connection.
func (c *conn) rollback(ctx context.Context) error {
if c.closed {
return errors.New("connection closed")
}
return nil
}

// transaction is a stub for driver.Tx.
type transaction struct {
conn *conn
}

func (t *transaction) Commit() error { return nil }
func (t *transaction) Rollback() error { return nil }

// Close marks the connection as closed so it cannot be reused.
func (c *conn) Close() error {
c.closed = true
return nil
}

// Compile-time interface checks.
var _ driver.ConnBeginTx = (*conn)(nil)
var _ driver.Tx = (*transaction)(nil)
var _ error = driver.ErrBadConn

func main() {
fmt.Println("Hello, Bounty Hunter!")

// Verify ErrBadConn is non-nil and wraps correctly.
if !errors.Is(driver.ErrBadConn, driver.ErrBadConn) {
panic("driver.ErrBadConn should be an error")
}
}