Transactions and Migrations
BEGIN/COMMIT patterns and schema migrations
Transactions and Migrations is a free Go Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Go Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Transactions in database/sql
Wrap operations in a transaction with db.BeginTx. Commit or rollback at the end; always defer a rollback to handle panics.
tx, err := db.BeginTx(ctx, nil)
if err != nil { return err }
defer tx.Rollback() // no-op after Commit
_, err = tx.ExecContext(ctx, "UPDATE accounts SET balance=balance-100 WHERE id=$1", from)
if err != nil { return err }
_, err = tx.ExecContext(ctx, "UPDATE accounts SET balance=balance+100 WHERE id=$1", to)
if err != nil { return err }
return tx.Commit()Transaction isolation levels
Pass sql.TxOptions to control isolation level:
tx, err := db.BeginTx(ctx, &sql.TxOptions{
Isolation: sql.LevelSerializable,
ReadOnly: false,
})Using the same Tx across functions
Pass the *sql.Tx to helper functions so they all participate in the same transaction. Do not call db.ExecContext inside a transaction — use tx.ExecContext.
Defer Rollback pattern
Defer rollback immediately after BeginTx. If Commit succeeds, the subsequent rollback is a no-op. If Commit fails, rollback reverts the changes.
tx, _ := db.BeginTx(ctx, nil)
defer tx.Rollback() // safe no-op after successful CommitSavepoints
Use savepoints within a transaction for partial rollbacks (PostgreSQL-specific via raw SQL):
tx.ExecContext(ctx, "SAVEPOINT sp1")
// ... work ...
tx.ExecContext(ctx, "ROLLBACK TO SAVEPOINT sp1") // partial rollbackDatabase migrations overview
Migrations are versioned SQL scripts that evolve the schema incrementally. Each migration has an up (apply) and down (revert) direction.
golang-migrate
github.com/golang-migrate/migrate/v4 runs versioned SQL migration files in order and tracks the applied version in a schema_migrations table.
m, _ := migrate.New("file://migrations", dsn)
m.Up() // apply all pending migrationsgoose
github.com/pressly/goose/v3 is another popular migration library supporting SQL and Go-function migrations with up/down commands.
goose.Up(db, "migrations")Atlas for schema management
Atlas provides declarative schema management: define the desired schema state and Atlas computes the diff and generates migration scripts automatically.
Running migrations at startup
Run migrations programmatically in main before starting the server to ensure the schema is up to date on deploy.
if err := runMigrations(db); err != nil { log.Fatal(err) }Migration best practices
Each migration: one concern, forward-compatible (additive). Never delete columns immediately — mark as deprecated, remove in a later migration after code no longer references them.
Quick Check
Why should you always defer tx.Rollback() immediately after BeginTx?
Recap: Transactions and Migrations
Key points:
- BeginTx → defer Rollback → work → Commit
- Pass *sql.Tx to helpers; use tx.ExecContext not db.ExecContext
- golang-migrate or goose for versioned SQL migrations
- Run migrations at startup; keep each migration additive
Frequently asked questions
Is the “Transactions and Migrations” lesson free?
Yes — the full text of “Transactions and Migrations” is free to read here on the web, and the Go Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Go Academy course, upgrade to CoddyKit PRO.
What will I learn in “Transactions and Migrations”?
BEGIN/COMMIT patterns and schema migrations You practise Go Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Go Academy?
No prior experience is required. Go Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Transactions and Migrations” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Go Academy lesson?
Yes. Every Go Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- database/sql and Drivers
- sqlx: Struct Scanning and Named Queries
- pgx: High-Performance PostgreSQL Driver
- Transactions and Migrations