0Pricing
Go Academy · Lesson

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 Commit

Savepoints

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 rollback

Database 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 migrations

goose

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

  1. database/sql and Drivers
  2. sqlx: Struct Scanning and Named Queries
  3. pgx: High-Performance PostgreSQL Driver
  4. Transactions and Migrations
← Back to Go Academy